summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
Diffstat (limited to 'src/map')
-rw-r--r--src/map/HPMmap.c70
-rw-r--r--src/map/HPMmap.h10
-rw-r--r--src/map/atcommand.h6
-rw-r--r--src/map/battle.h6
-rw-r--r--src/map/battleground.h6
-rw-r--r--src/map/buyingstore.h6
-rw-r--r--src/map/chat.h6
-rw-r--r--src/map/chrif.c46
-rw-r--r--src/map/chrif.h10
-rw-r--r--src/map/clif.h6
-rw-r--r--src/map/date.h6
-rw-r--r--src/map/duel.h6
-rw-r--r--src/map/elemental.h6
-rw-r--r--src/map/guild.h6
-rw-r--r--src/map/homunculus.h6
-rw-r--r--src/map/instance.h6
-rw-r--r--src/map/intif.h6
-rw-r--r--src/map/irc-bot.h6
-rw-r--r--src/map/itemdb.c94
-rw-r--r--src/map/itemdb.h13
-rw-r--r--src/map/log.h6
-rw-r--r--src/map/mail.h6
-rw-r--r--src/map/map.c120
-rw-r--r--src/map/map.h12
-rw-r--r--src/map/mapreg.h6
-rw-r--r--src/map/mercenary.h6
-rw-r--r--src/map/mob.h6
-rw-r--r--src/map/npc.c17
-rw-r--r--src/map/npc.h6
-rw-r--r--src/map/packets.h6
-rw-r--r--src/map/packets_struct.h6
-rw-r--r--src/map/party.h6
-rw-r--r--src/map/path.h6
-rw-r--r--src/map/pc.c70
-rw-r--r--src/map/pc.h22
-rw-r--r--src/map/pc_groups.h6
-rw-r--r--src/map/pet.h6
-rw-r--r--src/map/quest.h6
-rw-r--r--src/map/script.h6
-rw-r--r--src/map/searchstore.h6
-rw-r--r--src/map/skill.h6
-rw-r--r--src/map/status.c45
-rw-r--r--src/map/status.h6
-rw-r--r--src/map/storage.h6
-rw-r--r--src/map/trade.h7
-rw-r--r--src/map/unit.c8
-rw-r--r--src/map/unit.h11
-rw-r--r--src/map/vending.h6
48 files changed, 498 insertions, 255 deletions
diff --git a/src/map/HPMmap.c b/src/map/HPMmap.c
index 4b1338b8d..a67acfd16 100644
--- a/src/map/HPMmap.c
+++ b/src/map/HPMmap.c
@@ -34,6 +34,8 @@
#include <string.h>
#include <time.h>
+#include "../plugins/HPMDataCheck.h"
+
struct HPM_atcommand_list {
//tracking currently not enabled
// - requires modifying how plugins calls atcommand creation
@@ -46,6 +48,11 @@ struct HPM_atcommand_list {
struct HPM_atcommand_list *atcommand_list = NULL;
unsigned int atcommand_list_items = 0;
+/**
+ * (char*) data name -> (unsigned int) HPMDataCheck[] index
+ **/
+DBMap *datacheck_db;
+
bool HPM_map_grabHPData(struct HPDataOperationStorage *ret, enum HPluginDataTypes type, void *ptr) {
/* record address */
switch( type ) {
@@ -113,20 +120,27 @@ void HPM_map_atcommands(void) {
}
}
-void HPM_map_do_final(void) {
- unsigned char i;
+/**
+ * Called by HPM->DataCheck on a plugins incoming data, ensures data structs in use are matching!
+ **/
+bool HPM_map_DataCheck (struct s_HPMDataCheck *src, unsigned int size, char *name) {
+ unsigned int i, j;
- if( atcommand_list )
- aFree(atcommand_list);
- /**
- * why is pcg->HPM being cleared here? because PCG's do_final is not final,
- * is used on reload, and would thus cause plugin-provided permissions to go away
- **/
- for( i = 0; i < pcg->HPMpermissions_count; i++ ) {
- aFree(pcg->HPMpermissions[i].name);
+ for(i = 0; i < size; i++) {
+
+ if( !strdb_exists(datacheck_db, src[i].name) ) {
+ ShowError("HPMDataCheck:%s: '%s' was not found\n",name,src[i].name);
+ return false;
+ } else {
+ j = strdb_uiget(datacheck_db, src[i].name);/* not double lookup; exists sets cache to found data */
+ if( src[i].size != HPMDataCheck[j].size ) {
+ ShowWarning("HPMDataCheck:%s: '%s' size mismatch %u != %u\n",name,src[i].name,src[i].size,HPMDataCheck[j].size);
+ return false;
+ }
+ }
}
- if( pcg->HPMpermissions )
- aFree(pcg->HPMpermissions);
+
+ return true;
}
/**
@@ -141,3 +155,35 @@ void HPM_map_add_group_permission(unsigned int pluginID, char *name, unsigned in
pcg->HPMpermissions[index].name = aStrdup(name);
pcg->HPMpermissions[index].mask = mask;
}
+
+void HPM_map_do_init(void) {
+ unsigned int i;
+
+ /**
+ * Populates datacheck_db for easy lookup later on
+ **/
+ datacheck_db = strdb_alloc(DB_OPT_BASE,0);
+
+ for(i = 0; i < HPMDataCheckLen; i++) {
+ strdb_uiput(datacheck_db, HPMDataCheck[i].name, i);
+ }
+
+}
+
+void HPM_map_do_final(void) {
+ unsigned char i;
+
+ if( atcommand_list )
+ aFree(atcommand_list);
+ /**
+ * why is pcg->HPM being cleared here? because PCG's do_final is not final,
+ * is used on reload, and would thus cause plugin-provided permissions to go away
+ **/
+ for( i = 0; i < pcg->HPMpermissions_count; i++ ) {
+ aFree(pcg->HPMpermissions[i].name);
+ }
+ if( pcg->HPMpermissions )
+ aFree(pcg->HPMpermissions);
+
+ db_destroy(datacheck_db);
+}
diff --git a/src/map/HPMmap.h b/src/map/HPMmap.h
index ff8cf4c74..f291575fb 100644
--- a/src/map/HPMmap.h
+++ b/src/map/HPMmap.h
@@ -1,8 +1,8 @@
// Copyright (c) Hercules Dev Team, licensed under GNU GPL.
// See the LICENSE file
-#ifndef _HPM_MAP_
-#define _HPM_MAP_
+#ifndef _MAP_HPMMAP_H_
+#define _MAP_HPMMAP_H_
#include "../common/cbasetypes.h"
#include "../map/atcommand.h"
@@ -22,4 +22,8 @@ void HPM_map_do_final(void);
void HPM_map_add_group_permission(unsigned int pluginID, char *name, unsigned int *mask);
-#endif /* _HPM_MAP_ */
+bool HPM_map_DataCheck(struct s_HPMDataCheck *src, unsigned int size, char *name);
+
+void HPM_map_do_init(void);
+
+#endif /* _MAP_HPMMAP_H_ */
diff --git a/src/map/atcommand.h b/src/map/atcommand.h
index f95940924..39f7cc2b2 100644
--- a/src/map/atcommand.h
+++ b/src/map/atcommand.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _ATCOMMAND_H_
-#define _ATCOMMAND_H_
+#ifndef _MAP_ATCOMMAND_H_
+#define _MAP_ATCOMMAND_H_
#include "../common/conf.h"
#include "../common/db.h"
@@ -121,4 +121,4 @@ void atcommand_defaults(void);
/* stay here */
#define ACMD(x) static bool atcommand_ ## x (const int fd, struct map_session_data* sd, const char* command, const char* message, struct AtCommandInfo *info)
-#endif /* _ATCOMMAND_H_ */
+#endif /* _MAP_ATCOMMAND_H_ */
diff --git a/src/map/battle.h b/src/map/battle.h
index 98f2e37e8..0fcef7292 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _BATTLE_H_
-#define _BATTLE_H_
+#ifndef _MAP_BATTLE_H_
+#define _MAP_BATTLE_H_
#include "../common/cbasetypes.h"
#include "map.h" //ELE_MAX
@@ -596,4 +596,4 @@ struct battle_interface {
struct battle_interface *battle;
void battle_defaults(void);
-#endif /* _BATTLE_H_ */
+#endif /* _MAP_BATTLE_H_ */
diff --git a/src/map/battleground.h b/src/map/battleground.h
index 4aeb9f879..ed7347566 100644
--- a/src/map/battleground.h
+++ b/src/map/battleground.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _BATTLEGROUND_H_
-#define _BATTLEGROUND_H_
+#ifndef _MAP_BATTLEGROUND_H_
+#define _MAP_BATTLEGROUND_H_
#include "../common/mmo.h" // struct party
#include "clif.h"
@@ -112,4 +112,4 @@ struct battleground_interface *bg;
void battleground_defaults(void);
-#endif /* _BATTLEGROUND_H_ */
+#endif /* _MAP_BATTLEGROUND_H_ */
diff --git a/src/map/buyingstore.h b/src/map/buyingstore.h
index b0db40661..5141a1013 100644
--- a/src/map/buyingstore.h
+++ b/src/map/buyingstore.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _BUYINGSTORE_H_
-#define _BUYINGSTORE_H_
+#ifndef _MAP_BUYINGSTORE_H_
+#define _MAP_BUYINGSTORE_H_
/**
* Declarations
@@ -70,4 +70,4 @@ struct buyingstore_interface *buyingstore;
void buyingstore_defaults (void);
-#endif // _BUYINGSTORE_H_
+#endif // _MAP_BUYINGSTORE_H_
diff --git a/src/map/chat.h b/src/map/chat.h
index fcbadf008..71e5a11ec 100644
--- a/src/map/chat.h
+++ b/src/map/chat.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _CHAT_H_
-#define _CHAT_H_
+#ifndef _MAP_CHAT_H_
+#define _MAP_CHAT_H_
#include "map.h" // struct block_list, CHATROOM_TITLE_SIZE
@@ -55,4 +55,4 @@ struct chat_interface *chat;
void chat_defaults(void);
-#endif /* _CHAT_H_ */
+#endif /* _MAP_CHAT_H_ */
diff --git a/src/map/chrif.c b/src/map/chrif.c
index 3dc35fc68..c55b241e6 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -1561,6 +1561,50 @@ void chrif_send_report(char* buf, int len) {
}
/**
+ * Sends a single scdata for saving into char server, meant to ensure integrity of durationless conditions
+ **/
+void chrif_save_scdata_single(int account_id, int char_id, short type, struct status_change_entry *sce) {
+
+ if( !chrif->fd )
+ return;
+
+ WFIFOHEAD(chrif->fd, 28);
+
+ WFIFOW(chrif->fd, 0) = 0x2740;
+ WFIFOL(chrif->fd, 2) = account_id;
+ WFIFOL(chrif->fd, 6) = char_id;
+ WFIFOW(chrif->fd, 10) = type;
+ WFIFOL(chrif->fd, 12) = sce->val1;
+ WFIFOL(chrif->fd, 16) = sce->val2;
+ WFIFOL(chrif->fd, 20) = sce->val3;
+ WFIFOL(chrif->fd, 24) = sce->val4;
+
+ WFIFOSET(chrif->fd, 28);
+
+}
+/**
+ * Sends a single scdata deletion request into char server, meant to ensure integrity of durationless conditions
+ **/
+void chrif_del_scdata_single(int account_id, int char_id, short type) {
+
+ if( !chrif->fd ) {
+ ShowError("MAYDAY! failed to delete status %d from CID:%d/AID:%d\n",type,char_id,account_id);
+ return;
+ }
+
+
+ WFIFOHEAD(chrif->fd, 12);
+
+ WFIFOW(chrif->fd, 0) = 0x2741;
+ WFIFOL(chrif->fd, 2) = account_id;
+ WFIFOL(chrif->fd, 6) = char_id;
+ WFIFOW(chrif->fd, 10) = type;
+
+ WFIFOSET(chrif->fd, 12);
+
+}
+
+/** `
* @see DBApply
*/
int auth_db_final(DBKey key, DBData *data, va_list ap) {
@@ -1728,4 +1772,6 @@ void chrif_defaults(void) {
chrif->on_ready = chrif_on_ready;
chrif->on_disconnect = chrif_on_disconnect;
chrif->parse = chrif_parse;
+ chrif->save_scdata_single = chrif_save_scdata_single;
+ chrif->del_scdata_single = chrif_del_scdata_single;
}
diff --git a/src/map/chrif.h b/src/map/chrif.h
index 163fdf670..25e955604 100644
--- a/src/map/chrif.h
+++ b/src/map/chrif.h
@@ -2,13 +2,15 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _CHRIF_H_
-#define _CHRIF_H_
+#ifndef _MAP_CHRIF_H_
+#define _MAP_CHRIF_H_
#include "../common/cbasetypes.h"
#include <time.h>
#include "map.h" //TBL_stuff
+struct status_change_entry;
+
/**
* Defines
**/
@@ -140,6 +142,8 @@ struct chrif_interface {
void (*on_ready) (void);
void (*on_disconnect) (void);
int (*parse) (int fd);
+ void (*save_scdata_single) (int account_id, int char_id, short type, struct status_change_entry *sce);
+ void (*del_scdata_single) (int account_id, int char_id, short type);
};
struct chrif_interface *chrif;
@@ -148,4 +152,4 @@ void chrif_defaults(void);
// There's no need for another function when a simple macro can do exactly the same effect
#define chrif_char_offline(x) chrif->char_offline_nsd((x)->status.account_id,(x)->status.char_id)
-#endif /* _CHRIF_H_ */
+#endif /* _MAP_CHRIF_H_ */
diff --git a/src/map/clif.h b/src/map/clif.h
index 6405bbd3e..1e0319b7b 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _CLIF_H_
-#define _CLIF_H_
+#ifndef _MAP_CLIF_H_
+#define _MAP_CLIF_H_
#include "../common/cbasetypes.h"
#include "../common/db.h"
@@ -1275,4 +1275,4 @@ struct clif_interface *clif;
void clif_defaults(void);
-#endif /* _CLIF_H_ */
+#endif /* _MAP_CLIF_H_ */
diff --git a/src/map/date.h b/src/map/date.h
index cc19d88d1..02238d7ea 100644
--- a/src/map/date.h
+++ b/src/map/date.h
@@ -1,8 +1,8 @@
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder
-#ifndef _DATE_H_
-#define _DATE_H_
+#ifndef _MAP_DATE_H_
+#define _MAP_DATE_H_
int date_get_year(void);
int date_get_month(void);
@@ -15,4 +15,4 @@ int is_day_of_sun(void);
int is_day_of_moon(void);
int is_day_of_star(void);
-#endif /* _DATE_H_ */
+#endif /* _MAP_DATE_H_ */
diff --git a/src/map/duel.h b/src/map/duel.h
index d60c9531a..5405d2eee 100644
--- a/src/map/duel.h
+++ b/src/map/duel.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _DUEL_H_
-#define _DUEL_H_
+#ifndef _MAP_DUEL_H_
+#define _MAP_DUEL_H_
struct duel {
int members_count;
@@ -42,4 +42,4 @@ struct duel_interface *duel;
void duel_defaults(void);
-#endif /* _DUEL_H_ */
+#endif /* _MAP_DUEL_H_ */
diff --git a/src/map/elemental.h b/src/map/elemental.h
index 830a6a577..6d04a41a5 100644
--- a/src/map/elemental.h
+++ b/src/map/elemental.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _ELEMENTAL_H_
-#define _ELEMENTAL_H_
+#ifndef _MAP_ELEMENTAL_H_
+#define _MAP_ELEMENTAL_H_
#include "status.h" // struct status_data, struct status_change
#include "unit.h" // struct unit_data
@@ -120,4 +120,4 @@ struct elemental_interface *elemental;
void elemental_defaults(void);
-#endif /* _ELEMENTAL_H_ */
+#endif /* _MAP_ELEMENTAL_H_ */
diff --git a/src/map/guild.h b/src/map/guild.h
index 7878d75c3..b03bd664d 100644
--- a/src/map/guild.h
+++ b/src/map/guild.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _GUILD_H_
-#define _GUILD_H_
+#ifndef _MAP_GUILD_H_
+#define _MAP_GUILD_H_
//#include "../common/mmo.h"
#include "map.h" // NAME_LENGTH
@@ -173,4 +173,4 @@ struct guild_interface *guild;
void guild_defaults(void);
-#endif /* _GUILD_H_ */
+#endif /* _MAP_GUILD_H_ */
diff --git a/src/map/homunculus.h b/src/map/homunculus.h
index 117f9da8e..db250f511 100644
--- a/src/map/homunculus.h
+++ b/src/map/homunculus.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _HOMUNCULUS_H_
-#define _HOMUNCULUS_H_
+#ifndef _MAP_HOMUNCULUS_H_
+#define _MAP_HOMUNCULUS_H_
#include "status.h" // struct status_data, struct status_change
#include "unit.h" // struct unit_data
@@ -146,4 +146,4 @@ struct homunculus_interface *homun;
void homunculus_defaults(void);
-#endif /* _HOMUNCULUS_H_ */
+#endif /* _MAP_HOMUNCULUS_H_ */
diff --git a/src/map/instance.h b/src/map/instance.h
index 764a55b2b..66a7d0d6c 100644
--- a/src/map/instance.h
+++ b/src/map/instance.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _INSTANCE_H_
-#define _INSTANCE_H_
+#ifndef _MAP_INSTANCE_H_
+#define _MAP_INSTANCE_H_
#define INSTANCE_NAME_LENGTH (60+1)
@@ -82,4 +82,4 @@ struct instance_interface *instance;
void instance_defaults(void);
-#endif
+#endif /* _MAP_INSTANCE_H_ */
diff --git a/src/map/intif.h b/src/map/intif.h
index f0bb5c16e..290dcfcdc 100644
--- a/src/map/intif.h
+++ b/src/map/intif.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _INTIF_H_
-#define _INFIF_H_
+#ifndef _MAP_INTIF_H_
+#define _MAP_INTIF_H_
/**
@@ -183,4 +183,4 @@ struct intif_interface *intif;
void intif_defaults(void);
-#endif /* _INTIF_H_ */
+#endif /* _MAP_INTIF_H_ */
diff --git a/src/map/irc-bot.h b/src/map/irc-bot.h
index 7d6a19eba..c15a5d46a 100644
--- a/src/map/irc-bot.h
+++ b/src/map/irc-bot.h
@@ -3,8 +3,8 @@
// Base Author: shennetsind @ http://hercules.ws
-#ifndef _IRC_BOT_H_
-#define _IRC_BOT_H_
+#ifndef _MAP_IRC_BOT_H_
+#define _MAP_IRC_BOT_H_
#define IRC_NICK_LENGTH 40
#define IRC_IDENT_LENGTH 40
@@ -61,4 +61,4 @@ struct irc_bot_interface *ircbot;
void ircbot_defaults(void);
-#endif /* _IRC_BOT_H_ */
+#endif /* _MAP_IRC_BOT_H_ */
diff --git a/src/map/itemdb.c b/src/map/itemdb.c
index 6db503214..527972516 100644
--- a/src/map/itemdb.c
+++ b/src/map/itemdb.c
@@ -1449,8 +1449,7 @@ void itemdb_read_combos() {
} else {
int items[MAX_ITEMS_PER_COMBO];
int v = 0, retcount = 0;
- struct item_data * id = NULL;
- int idx = 0;
+ struct item_combo *combo = NULL;
if((retcount = itemdb->combo_split_atoi(str[0], items)) < 2) {
ShowError("itemdb_read_combos: line %d of \"%s\" doesn't have enough items to make for a combo (min:2), skipping.\n", lines, filepath);
@@ -1467,33 +1466,23 @@ void itemdb_read_combos() {
/* failed at some item */
if( v < retcount )
continue;
-
- id = itemdb->exists(items[0]);
-
- idx = id->combos_count;
- /* first entry, create */
- if( id->combos == NULL ) {
- CREATE(id->combos, struct item_combo*, 1);
- id->combos_count = 1;
- } else {
- RECREATE(id->combos, struct item_combo*, ++id->combos_count);
- }
+ RECREATE(itemdb->combos, struct item_combo*, ++itemdb->combo_count);
- CREATE(id->combos[idx],struct item_combo,1);
+ CREATE(combo, struct item_combo, 1);
- id->combos[idx]->nameid = aMalloc( retcount * sizeof(unsigned short) );
- id->combos[idx]->count = retcount;
- id->combos[idx]->script = script->parse(str[1], filepath, lines, 0);
- id->combos[idx]->id = count;
- id->combos[idx]->isRef = false;
+ combo->count = retcount;
+ combo->script = script->parse(str[1], filepath, lines, 0);
+ combo->id = itemdb->combo_count - 1;
/* populate ->nameid field */
for( v = 0; v < retcount; v++ ) {
- id->combos[idx]->nameid[v] = items[v];
+ combo->nameid[v] = items[v];
}
- /* populate the children to refer to this combo */
- for( v = 1; v < retcount; v++ ) {
+ itemdb->combos[itemdb->combo_count - 1] = combo;
+
+ /* populate the items to refer to this combo */
+ for( v = 0; v < retcount; v++ ) {
struct item_data * it;
int index;
@@ -1501,19 +1490,9 @@ void itemdb_read_combos() {
index = it->combos_count;
- if( it->combos == NULL ) {
- CREATE(it->combos, struct item_combo*, 1);
- it->combos_count = 1;
- } else {
- RECREATE(it->combos, struct item_combo*, ++it->combos_count);
- }
-
- CREATE(it->combos[index],struct item_combo,1);
+ RECREATE(it->combos, struct item_combo*, ++it->combos_count);
- /* we copy previously alloc'd pointers and just set it to reference */
- memcpy(it->combos[index],id->combos[idx],sizeof(struct item_combo));
- /* we flag this way to ensure we don't double-dealloc same data */
- it->combos[index]->isRef = true;
+ it->combos[index] = combo;
}
}
@@ -2076,6 +2055,15 @@ void itemdb_read(bool minimal) {
itemdb->uid_load();
}
+/**
+ * retrieves item_combo data by combo id
+ **/
+struct item_combo * itemdb_id2combo( unsigned short id ) {
+ if( id > itemdb->combo_count )
+ return NULL;
+ return itemdb->combos[id];
+}
+
/*==========================================
* Initialize / Finalize
*------------------------------------------*/
@@ -2092,17 +2080,8 @@ void destroy_item_data(struct item_data* self, int free_self)
script->free_code(self->equip_script);
if( self->unequip_script )
script->free_code(self->unequip_script);
- if( self->combos_count ) {
- int i;
- for( i = 0; i < self->combos_count; i++ ) {
- if( !self->combos[i]->isRef ) {
- aFree(self->combos[i]->nameid);
- script->free_code(self->combos[i]->script);
- }
- aFree(self->combos[i]);
- }
+ if( self->combos )
aFree(self->combos);
- }
#if defined(DEBUG)
// trash item
memset(self, 0xDD, sizeof(struct item_data));
@@ -2169,6 +2148,16 @@ void itemdb_clear(bool total) {
itemdb->packages = NULL;
itemdb->package_count = 0;
+ for(i = 0; i < itemdb->combo_count; i++) {
+ script->free_code(itemdb->combos[i]->script);
+ aFree(itemdb->combos[i]);
+ }
+ if( itemdb->combos )
+ aFree(itemdb->combos);
+
+ itemdb->combos = NULL;
+ itemdb->combo_count = 0;
+
if( total )
return;
@@ -2225,18 +2214,15 @@ void itemdb_reload(void) {
pc->setinventorydata(sd);
if( battle_config.item_check )
sd->state.itemcheck = 1;
- pc->checkitem(sd);
/* clear combo bonuses */
- if( sd->combos.count ) {
- aFree(sd->combos.bonus);
- aFree(sd->combos.id);
- sd->combos.bonus = NULL;
- sd->combos.id = NULL;
- sd->combos.count = 0;
+ if( sd->combo_count ) {
+ aFree(sd->combos);
+ sd->combos = NULL;
+ sd->combo_count = 0;
if( pc->load_combo(sd) > 0 )
status_calc_pc(sd,SCO_FORCE);
}
-
+ pc->checkitem(sd);
}
mapit->free(iter);
}
@@ -2286,6 +2272,9 @@ void itemdb_defaults(void) {
itemdb->packages = NULL;
itemdb->package_count = 0;
/* */
+ itemdb->combos = NULL;
+ itemdb->combo_count = 0;
+ /* */
itemdb->names = NULL;
/* */
/* itemdb->array is cleared on itemdb->init() */
@@ -2352,4 +2341,5 @@ void itemdb_defaults(void) {
itemdb->destroy_item_data = destroy_item_data;
itemdb->final_sub = itemdb_final_sub;
itemdb->clear = itemdb_clear;
+ itemdb->id2combo = itemdb_id2combo;
}
diff --git a/src/map/itemdb.h b/src/map/itemdb.h
index b3ff606df..c399a0442 100644
--- a/src/map/itemdb.h
+++ b/src/map/itemdb.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _ITEMDB_H_
-#define _ITEMDB_H_
+#ifndef _MAP_ITEMDB_H_
+#define _MAP_ITEMDB_H_
#include "../common/db.h"
#include "../common/mmo.h" // ITEM_NAME_LENGTH
@@ -400,10 +400,9 @@ struct item_data {
struct item_combo {
struct script_code *script;
- unsigned short *nameid;/* nameid array */
+ unsigned short nameid[MAX_ITEMS_PER_COMBO];/* nameid array */
unsigned char count;
unsigned short id;/* id of this combo */
- bool isRef;/* whether this struct is a reference or the master */
};
struct item_group {
@@ -509,6 +508,9 @@ struct itemdb_interface {
/* */
struct item_package *packages;
unsigned short package_count;
+ /* list of item combos loaded */
+ struct item_combo **combos;
+ unsigned short combo_count;
/* */
DBMap *names;
/* */
@@ -576,10 +578,11 @@ struct itemdb_interface {
void (*destroy_item_data) (struct item_data *self, int free_self);
int (*final_sub) (DBKey key, DBData *data, va_list ap);
void (*clear) (bool total);
+ struct item_combo * (*id2combo) (unsigned short id);
};
struct itemdb_interface *itemdb;
void itemdb_defaults(void);
-#endif /* _ITEMDB_H_ */
+#endif /* _MAP_ITEMDB_H_ */
diff --git a/src/map/log.h b/src/map/log.h
index 9864a54d7..b2cb92c20 100644
--- a/src/map/log.h
+++ b/src/map/log.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _LOG_H_
-#define _LOG_H_
+#ifndef _MAP_LOG_H_
+#define _MAP_LOG_H_
#include "../common/cbasetypes.h"
#include "../common/sql.h"
@@ -134,4 +134,4 @@ struct log_interface *logs;
void log_defaults(void);
-#endif /* _LOG_H_ */
+#endif /* _MAP_LOG_H_ */
diff --git a/src/map/mail.h b/src/map/mail.h
index b2b9048cb..8df537ff3 100644
--- a/src/map/mail.h
+++ b/src/map/mail.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _MAIL_H_
-#define _MAIL_H_
+#ifndef _MAP_MAIL_H_
+#define _MAP_MAIL_H_
#include "../common/mmo.h"
@@ -23,4 +23,4 @@ struct mail_interface *mail;
void mail_defaults(void);
-#endif /* _MAIL_H_ */
+#endif /* _MAP_MAIL_H_ */
diff --git a/src/map/map.c b/src/map/map.c
index 33721b028..74b81f467 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -3675,14 +3675,115 @@ int map_sql_close(void)
return 0;
}
+/**
+ * Merges two zones into a new one
+ * @param main the zone whose data must override the others upon conflict,
+ * e.g. enabling pvp on a town means that main is the pvp zone, while "other" is the towns previous zone
+ *
+ * @return the newly created zone from merging main and other
+ **/
+struct map_zone_data *map_merge_zone(struct map_zone_data *main, struct map_zone_data *other) {
+ char newzone[MAP_ZONE_NAME_LENGTH];
+ struct map_zone_data *zone = NULL;
+ int cursor, i;
+
+ sprintf(newzone, "%s+%s",main->name,other->name);
+
+ if( (zone = strdb_get(map->zone_db, newzone)) )
+ return zone;/* this zone has already been merged */
+
+ CREATE(zone, struct map_zone_data, 1);
+
+ safestrncpy(zone->name, newzone, MAP_ZONE_NAME_LENGTH);
+
+ zone->disabled_skills_count = main->disabled_skills_count + other->disabled_skills_count;
+ zone->disabled_items_count = main->disabled_items_count + other->disabled_items_count;
+ zone->mapflags_count = main->mapflags_count + other->mapflags_count;
+ zone->disabled_commands_count = main->disabled_commands_count + other->disabled_commands_count;
+ zone->capped_skills_count = main->capped_skills_count + other->capped_skills_count;
+
+ CREATE(zone->disabled_skills, struct map_zone_disabled_skill_entry *, zone->disabled_skills_count );
+
+ for(i = 0, cursor = 0; i < main->disabled_skills_count; i++, cursor++ ) {
+ CREATE(zone->disabled_skills[cursor], struct map_zone_disabled_skill_entry, 1 );
+ memcpy(zone->disabled_skills[cursor], main->disabled_skills[i], sizeof(struct map_zone_disabled_skill_entry));
+ }
+
+ for(i = 0; i < other->disabled_skills_count; i++, cursor++ ) {
+ CREATE(zone->disabled_skills[cursor], struct map_zone_disabled_skill_entry, 1 );
+ memcpy(zone->disabled_skills[cursor], other->disabled_skills[i], sizeof(struct map_zone_disabled_skill_entry));
+ }
+
+ CREATE(zone->disabled_items, int, zone->disabled_items_count );
+
+ for(i = 0, cursor = 0; i < main->disabled_items_count; i++, cursor++ ) {
+ zone->disabled_items[cursor] = main->disabled_items[i];
+ }
+
+ for(i = 0; i < other->disabled_items_count; i++, cursor++ ) {
+ zone->disabled_items[cursor] = other->disabled_items[i];
+ }
+
+ CREATE(zone->mapflags, char *, zone->mapflags_count );
+
+ for(i = 0, cursor = 0; i < main->mapflags_count; i++, cursor++ ) {
+ CREATE(zone->mapflags[cursor], char, MAP_ZONE_MAPFLAG_LENGTH );
+ safestrncpy(zone->mapflags[cursor], main->mapflags[i], MAP_ZONE_MAPFLAG_LENGTH);
+ }
+
+ for(i = 0; i < other->mapflags_count; i++, cursor++ ) {
+ CREATE(zone->mapflags[cursor], char, MAP_ZONE_MAPFLAG_LENGTH );
+ safestrncpy(zone->mapflags[cursor], other->mapflags[i], MAP_ZONE_MAPFLAG_LENGTH);
+ }
+
+ CREATE(zone->disabled_commands, struct map_zone_disabled_command_entry *, zone->disabled_commands_count);
+
+ for(i = 0, cursor = 0; i < main->disabled_commands_count; i++, cursor++ ) {
+ CREATE(zone->disabled_commands[cursor], struct map_zone_disabled_command_entry, 1);
+ memcpy(zone->disabled_commands[cursor], main->disabled_commands[i], sizeof(struct map_zone_disabled_command_entry));
+ }
+
+ for(i = 0; i < other->disabled_commands_count; i++, cursor++ ) {
+ CREATE(zone->disabled_commands[cursor], struct map_zone_disabled_command_entry, 1);
+ memcpy(zone->disabled_commands[cursor], other->disabled_commands[i], sizeof(struct map_zone_disabled_command_entry));
+ }
+
+ CREATE(zone->capped_skills, struct map_zone_skill_damage_cap_entry *, zone->capped_skills_count);
+
+
+ for(i = 0, cursor = 0; i < main->capped_skills_count; i++, cursor++ ) {
+ CREATE(zone->capped_skills[cursor], struct map_zone_skill_damage_cap_entry, 1);
+ memcpy(zone->capped_skills[cursor], main->disabled_commands[i], sizeof(struct map_zone_skill_damage_cap_entry));
+ }
+
+ for(i = 0; i < other->capped_skills_count; i++, cursor++ ) {
+ CREATE(zone->capped_skills[cursor], struct map_zone_skill_damage_cap_entry, 1);
+ memcpy(zone->capped_skills[cursor], other->capped_skills[i], sizeof(struct map_zone_skill_damage_cap_entry));
+ }
+
+ zone->info.special = 2;
+
+ strdb_put(map->zone_db, newzone, zone);
+
+ return zone;
+}
+
void map_zone_change2(int m, struct map_zone_data *zone) {
char empty[1] = "\0";
- map->list[m].prev_zone = map->list[m].zone;
-
+ if( map->list[m].zone == zone )
+ return;
+
+ if( map->list[m].zone->info.special != 2 ) /* we don't update it for merged zones! */
+ map->list[m].prev_zone = map->list[m].zone;
+
if( map->list[m].zone_mf_count )
map->zone_remove(m);
+ if( zone->info.special ) {
+ zone = map->merge_zone(zone,map->list[m].prev_zone);
+ }
+
map->zone_apply(m,zone,empty,empty,empty);
}
/* when changing from a mapflag to another during runtime */
@@ -4640,7 +4741,7 @@ void read_map_zone_db(void) {
zone->disabled_skills_count = 0;
zone->disabled_items_count = 0;
}
- safestrncpy(zone->name, zonename, MAP_ZONE_NAME_LENGTH);
+ safestrncpy(zone->name, zonename, MAP_ZONE_NAME_LENGTH/2);
if( (skills = libconfig->setting_get_member(zone_e, "disabled_skills")) != NULL ) {
disabled_skills_count = libconfig->setting_length(skills);
@@ -4981,6 +5082,14 @@ void read_map_zone_db(void) {
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 */
libconfig->destroy(&map_zone_db);
+
+ /* post-load processing */
+ if( (zone = strdb_get(map->zone_db, MAP_ZONE_PVP_NAME)) )
+ zone->info.special = 1;
+ if( (zone = strdb_get(map->zone_db, MAP_ZONE_GVG_NAME)) )
+ zone->info.special = 1;
+ if( (zone = strdb_get(map->zone_db, MAP_ZONE_BG_NAME)) )
+ zone->info.special = 1;
}
}
@@ -5447,6 +5556,8 @@ int do_init(int argc, char *argv[])
map_load_defaults();
+ HPM_map_do_init();
+ HPM->DataCheck = HPM_map_DataCheck;
HPM->load_sub = HPM_map_plugin_load_sub;
HPM->symbol_defaults_sub = map_hp_symbols;
HPM->grabHPDataSub = HPM_map_grabHPData;
@@ -5941,6 +6052,8 @@ void map_defaults(void) {
map->add_questinfo = map_add_questinfo;
map->remove_questinfo = map_remove_questinfo;
+ map->merge_zone = map_merge_zone;
+
/**
* mapit interface
**/
@@ -5954,4 +6067,5 @@ void map_defaults(void) {
mapit->next = mapit_next;
mapit->prev = mapit_prev;
mapit->exists = mapit_exists;
+
}
diff --git a/src/map/map.h b/src/map/map.h
index 130b181da..a4e9499b3 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _MAP_H_
-#define _MAP_H_
+#ifndef _MAP_MAP_H_
+#define _MAP_MAP_H_
#include "../common/cbasetypes.h"
#include "../common/core.h" // CORE_ST_LAST
@@ -531,7 +531,7 @@ struct map_zone_skill_damage_cap_entry {
enum map_zone_skill_subtype subtype;
};
-#define MAP_ZONE_NAME_LENGTH 30
+#define MAP_ZONE_NAME_LENGTH 60
#define MAP_ZONE_ALL_NAME "All"
#define MAP_ZONE_NORMAL_NAME "Normal"
#define MAP_ZONE_PVP_NAME "PvP"
@@ -552,6 +552,9 @@ struct map_zone_data {
int disabled_commands_count;
struct map_zone_skill_damage_cap_entry **capped_skills;
int capped_skills_count;
+ struct {
+ unsigned int special : 2;/* 1: whether this is a mergeable zone; 2: whether it is a merged zone */
+ } info;
};
struct map_drop_list {
@@ -1060,10 +1063,11 @@ struct map_interface {
int (*get_new_bonus_id) (void);
void (*add_questinfo) (int m, struct questinfo *qi);
bool (*remove_questinfo) (int m, struct npc_data *nd);
+ struct map_zone_data *(*merge_zone) (struct map_zone_data *main, struct map_zone_data *other);
};
struct map_interface *map;
void map_defaults(void);
-#endif /* _MAP_H_ */
+#endif /* _MAP_MAP_H_ */
diff --git a/src/map/mapreg.h b/src/map/mapreg.h
index 157e634cc..c92b6f602 100644
--- a/src/map/mapreg.h
+++ b/src/map/mapreg.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _MAPREG_H_
-#define _MAPREG_H_
+#ifndef _MAP_MAPREG_H_
+#define _MAP_MAPREG_H_
#include "../common/cbasetypes.h"
#include "../common/db.h"
@@ -51,4 +51,4 @@ struct mapreg_interface *mapreg;
void mapreg_defaults(void);
-#endif /* _MAPREG_H_ */
+#endif /* _MAP_MAPREG_H_ */
diff --git a/src/map/mercenary.h b/src/map/mercenary.h
index 3f2214b65..dd9266b2e 100644
--- a/src/map/mercenary.h
+++ b/src/map/mercenary.h
@@ -1,8 +1,8 @@
// Copyright (c) Hercules Dev Team, licensed under GNU GPL.
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _MERCENARY_H_
-#define _MERCENARY_H_
+#ifndef _MAP_MERCENARY_H_
+#define _MAP_MERCENARY_H_
#include "status.h" // struct status_data, struct status_change
#include "unit.h" // struct unit_data
@@ -98,4 +98,4 @@ struct mercenary_interface *mercenary;
void mercenary_defaults(void);
-#endif /* _MERCENARY_H_ */
+#endif /* _MAP_MERCENARY_H_ */
diff --git a/src/map/mob.h b/src/map/mob.h
index 9321cb4fd..80175b1db 100644
--- a/src/map/mob.h
+++ b/src/map/mob.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _MOB_H_
-#define _MOB_H_
+#ifndef _MAP_MOB_H_
+#define _MAP_MOB_H_
#include "../common/mmo.h" // struct item
#include "guild.h" // struct guardian_data
@@ -364,4 +364,4 @@ struct mob_interface *mob;
void mob_defaults(void);
-#endif /* _MOB_H_ */
+#endif /* _MAP_MOB_H_ */
diff --git a/src/map/npc.c b/src/map/npc.c
index 458fc52ed..36efc7267 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -3173,12 +3173,17 @@ void npc_unsetcells(struct npc_data* nd) {
int16 m = nd->bl.m, x = nd->bl.x, y = nd->bl.y, xs, ys;
int i,j, x0, x1, y0, y1;
- if (nd->subtype == WARP) {
- xs = nd->u.warp.xs;
- ys = nd->u.warp.ys;
- } else {
- xs = nd->u.scr.xs;
- ys = nd->u.scr.ys;
+ switch(nd->subtype) {
+ case WARP:
+ xs = nd->u.warp.xs;
+ ys = nd->u.warp.ys;
+ break;
+ case SCRIPT:
+ xs = nd->u.scr.xs;
+ ys = nd->u.scr.ys;
+ break;
+ default:
+ return; // Other types doesn't have touch area
}
if (m < 0 || xs < 0 || ys < 0 || map->list[m].cell == (struct mapcell *)0xdeadbeaf)
diff --git a/src/map/npc.h b/src/map/npc.h
index 266d174fb..719974ac4 100644
--- a/src/map/npc.h
+++ b/src/map/npc.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _NPC_H_
-#define _NPC_H_
+#ifndef _MAP_NPC_H_
+#define _MAP_NPC_H_
#include "map.h" // struct block_list
#include "status.h" // struct status_change
@@ -346,4 +346,4 @@ struct pcre_interface *libpcre;
void npc_chat_defaults(void);
#endif
-#endif /* _NPC_H_ */
+#endif /* _MAP_NPC_H_ */
diff --git a/src/map/packets.h b/src/map/packets.h
index cea916f6d..4cf6f6d6a 100644
--- a/src/map/packets.h
+++ b/src/map/packets.h
@@ -3,8 +3,8 @@
//Included directly by clif.h in packet_loaddb()
-#ifndef _PACKETS_H_
-#define _PACKETS_H_
+#ifndef _MAP_PACKETS_H_
+#define _MAP_PACKETS_H_
#ifndef packet
#define packet(a,b,...)
@@ -2693,4 +2693,4 @@ packet(0x020d,-1);
packetKeys(OBFUSCATIONKEY1,OBFUSCATIONKEY2,OBFUSCATIONKEY3);
#endif
-#endif /* _PACKETS_H_ */
+#endif /* _MAP_PACKETS_H_ */
diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h
index 1156f4465..4a599463a 100644
--- a/src/map/packets_struct.h
+++ b/src/map/packets_struct.h
@@ -3,8 +3,8 @@
/* Hercules Renewal: Phase Two http://hercules.ws/board/topic/383-hercules-renewal-phase-two/ */
-#ifndef _PACKETS_STRUCT_H_
-#define _PACKETS_STRUCT_H_
+#ifndef _MAP_PACKETS_STRUCT_H_
+#define _MAP_PACKETS_STRUCT_H_
#include "../common/mmo.h"
@@ -945,4 +945,4 @@ struct packet_npc_market_open {
#pragma pack(pop)
#endif // not NetBSD < 6 / Solaris
-#endif /* _PACKETS_STRUCT_H_ */
+#endif /* _MAP_PACKETS_STRUCT_H_ */
diff --git a/src/map/party.h b/src/map/party.h
index 051c98af2..05b5309e6 100644
--- a/src/map/party.h
+++ b/src/map/party.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _PARTY_H_
-#define _PARTY_H_
+#ifndef _MAP_PARTY_H_
+#define _MAP_PARTY_H_
#include "../common/mmo.h" // struct party
#include "../config/core.h"
@@ -141,4 +141,4 @@ struct party_interface *party;
void party_defaults(void);
-#endif /* _PARTY_H_ */
+#endif /* _MAP_PARTY_H_ */
diff --git a/src/map/path.h b/src/map/path.h
index a889a6409..0b67a0120 100644
--- a/src/map/path.h
+++ b/src/map/path.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _PATH_H_
-#define _PATH_H_
+#ifndef _MAP_PATH_H_
+#define _MAP_PATH_H_
#include "map.h" // enum cell_chk
@@ -46,4 +46,4 @@ struct path_interface *path;
void path_defaults(void);
-#endif /* _PATH_H_ */
+#endif /* _MAP_PATH_H_ */
diff --git a/src/map/pc.c b/src/map/pc.c
index acbdd8df5..7ca582b86 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -8446,17 +8446,19 @@ int pc_cleareventtimer(struct map_session_data *sd)
/* called when a item with combo is worn */
int pc_checkcombo(struct map_session_data *sd, struct item_data *data ) {
int i, j, k, z;
- int index, idx, success = 0;
+ int index, success = 0;
+ struct pc_combos *combo;
for( i = 0; i < data->combos_count; i++ ) {
/* ensure this isn't a duplicate combo */
- if( sd->combos.bonus != NULL ) {
+ if( sd->combos != NULL ) {
int x;
- ARR_FIND( 0, sd->combos.count, x, sd->combos.id[x] == data->combos[i]->id );
+
+ ARR_FIND( 0, sd->combo_count, x, sd->combos[x].id == data->combos[i]->id );
/* found a match, skip this combo */
- if( x < sd->combos.count )
+ if( x < sd->combo_count )
continue;
}
@@ -8473,7 +8475,7 @@ int pc_checkcombo(struct map_session_data *sd, struct item_data *data ) {
if(!sd->inventory_data[index])
continue;
-
+
if ( itemdb_type(id) != IT_CARD ) {
if ( sd->inventory_data[index]->nameid != id )
continue;
@@ -8507,22 +8509,13 @@ int pc_checkcombo(struct map_session_data *sd, struct item_data *data ) {
/* we got here, means all items in the combo are matching */
- idx = sd->combos.count;
-
- if( sd->combos.bonus == NULL ) {
- CREATE(sd->combos.bonus, struct script_code *, 1);
- CREATE(sd->combos.id, unsigned short, 1);
- sd->combos.count = 1;
- } else {
- RECREATE(sd->combos.bonus, struct script_code *, ++sd->combos.count);
- RECREATE(sd->combos.id, unsigned short, sd->combos.count);
- }
-
- /* we simply copy the pointer */
- sd->combos.bonus[idx] = data->combos[i]->script;
- /* save this combo's id */
- sd->combos.id[idx] = data->combos[i]->id;
-
+ RECREATE(sd->combos, struct pc_combos, ++sd->combo_count);
+
+ combo = &sd->combos[sd->combo_count - 1];
+
+ combo->bonus = data->combos[i]->script;
+ combo->id = data->combos[i]->id;
+
success++;
}
return success;
@@ -8532,26 +8525,30 @@ int pc_checkcombo(struct map_session_data *sd, struct item_data *data ) {
int pc_removecombo(struct map_session_data *sd, struct item_data *data ) {
int i, retval = 0;
- if( sd->combos.bonus == NULL )
+ if( !sd->combos )
return 0;/* nothing to do here, player has no combos */
+
for( i = 0; i < data->combos_count; i++ ) {
/* check if this combo exists in this user */
int x = 0, cursor = 0, j;
- ARR_FIND( 0, sd->combos.count, x, sd->combos.id[x] == data->combos[i]->id );
+
+ ARR_FIND( 0, sd->combo_count, x, sd->combos[x].id == data->combos[i]->id );
/* no match, skip this combo */
- if( !(x < sd->combos.count) )
+ if( !(x < sd->combo_count) )
continue;
- sd->combos.bonus[x] = NULL;
- sd->combos.id[x] = 0;
+ sd->combos[x].bonus = NULL;
+ sd->combos[x].id = 0;
+
retval++;
- for( j = 0, cursor = 0; j < sd->combos.count; j++ ) {
- if( sd->combos.bonus[j] == NULL )
+
+ for( j = 0, cursor = 0; j < sd->combo_count; j++ ) {
+ if( sd->combos[j].bonus == NULL )
continue;
if( cursor != j ) {
- sd->combos.bonus[cursor] = sd->combos.bonus[j];
- sd->combos.id[cursor] = sd->combos.id[j];
+ sd->combos[cursor].bonus = sd->combos[j].bonus;
+ sd->combos[cursor].id = sd->combos[j].id;
}
cursor++;
@@ -8562,11 +8559,10 @@ int pc_removecombo(struct map_session_data *sd, struct item_data *data ) {
continue;
/* it's empty, we can clear all the memory */
- if( (sd->combos.count = cursor) == 0 ) {
- aFree(sd->combos.bonus);
- aFree(sd->combos.id);
- sd->combos.bonus = NULL;
- sd->combos.id = NULL;
+ if( (sd->combo_count = cursor) == 0 ) {
+ aFree(sd->combos);
+ sd->combos = NULL;
+
return retval; /* we also can return at this point for we have no more combos to check */
}
@@ -8989,7 +8985,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) {
*------------------------------------------*/
int pc_checkitem(struct map_session_data *sd)
{
- int i,id,calc_flag = 0;
+ int i, id, calc_flag = 0;
nullpo_ret(sd);
@@ -9055,7 +9051,7 @@ int pc_checkitem(struct map_session_data *sd)
}
}
-
+
if( calc_flag && sd->state.active ) {
pc->checkallowskill(sd);
status_calc_pc(sd,SCO_NONE);
diff --git a/src/map/pc.h b/src/map/pc.h
index 808f6c52c..30a24c00e 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -1,8 +1,9 @@
// Copyright (c) Hercules Dev Team, licensed under GNU GPL.
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _PC_H_
-#define _PC_H_
+
+#ifndef _MAP_PC_H_
+#define _MAP_PC_H_
#include "../common/mmo.h" // JOB_*, MAX_FAME_LIST, struct fame_list, struct mmo_charstatus
#include "../common/ers.h"
@@ -115,6 +116,12 @@ enum npc_timeout_type {
NPCT_MENU = 1,
NPCT_WAIT = 2,
};
+
+struct pc_combos {
+ struct script_code *bonus;/* the script of the combo */
+ unsigned short id;/* this combo id */
+};
+
struct map_session_data {
struct block_list bl;
struct unit_data ud;
@@ -467,12 +474,9 @@ struct map_session_data {
enum npc_timeout_type npc_idle_type;
#endif
- struct {
- struct script_code **bonus;/* the script */
- unsigned short *id;/* array of combo ids */
- unsigned char count;
- } combos;
-
+ struct pc_combos *combos;
+ unsigned char combo_count;
+
/**
* Guarantees your friend request is legit (for bugreport:4629)
**/
@@ -1045,4 +1049,4 @@ struct pc_interface *pc;
void pc_defaults(void);
-#endif /* _PC_H_ */
+#endif /* _MAP_PC_H_ */
diff --git a/src/map/pc_groups.h b/src/map/pc_groups.h
index 3396512ea..5c03f999f 100644
--- a/src/map/pc_groups.h
+++ b/src/map/pc_groups.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _PC_GROUPS_H_
-#define _PC_GROUPS_H_
+#ifndef _MAP_PC_GROUPS_H_
+#define _MAP_PC_GROUPS_H_
/// PC permissions
enum e_pc_permission {
@@ -92,4 +92,4 @@ struct pc_groups_interface *pcg;
void pc_groups_defaults(void);
-#endif // _PC_GROUPS_H_
+#endif /* _MAP_PC_GROUPS_H_ */
diff --git a/src/map/pet.h b/src/map/pet.h
index f1a219700..537a50c4b 100644
--- a/src/map/pet.h
+++ b/src/map/pet.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _PET_H_
-#define _PET_H_
+#ifndef _MAP_PET_H_
+#define _MAP_PET_H_
#define MAX_PET_DB 300
#define MAX_PETLOOT_SIZE 30
@@ -152,4 +152,4 @@ struct pet_interface *pet;
void pet_defaults(void);
-#endif /* _PET_H_ */
+#endif /* _MAP_PET_H_ */
diff --git a/src/map/quest.h b/src/map/quest.h
index 28815a6c3..e01e35619 100644
--- a/src/map/quest.h
+++ b/src/map/quest.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _QUEST_H_
-#define _QUEST_H_
+#ifndef _MAP_QUEST_H_
+#define _MAP_QUEST_H_
#define MAX_QUEST_DB (60355+1) // Highest quest ID + 1
@@ -48,4 +48,4 @@ struct quest_interface *quest;
void quest_defaults(void);
-#endif
+#endif /* _MAP_QUEST_H_ */
diff --git a/src/map/script.h b/src/map/script.h
index 97db2a775..b7e9e5741 100644
--- a/src/map/script.h
+++ b/src/map/script.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _SCRIPT_H_
-#define _SCRIPT_H_
+#ifndef _MAP_SCRIPT_H_
+#define _MAP_SCRIPT_H_
#include "../common/strlib.h" //StringBuf
#include "../common/cbasetypes.h"
@@ -700,4 +700,4 @@ struct script_interface *script;
void script_defaults(void);
-#endif /* _SCRIPT_H_ */
+#endif /* _MAP_SCRIPT_H_ */
diff --git a/src/map/searchstore.h b/src/map/searchstore.h
index d7a327181..827e39053 100644
--- a/src/map/searchstore.h
+++ b/src/map/searchstore.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _SEARCHSTORE_H_
-#define _SEARCHSTORE_H_
+#ifndef _MAP_SEARCHSTORE_H_
+#define _MAP_SEARCHSTORE_H_
/**
* Defines
@@ -93,4 +93,4 @@ struct searchstore_interface *searchstore;
void searchstore_defaults (void);
-#endif // _SEARCHSTORE_H_
+#endif /* _MAP_SEARCHSTORE_H_ */
diff --git a/src/map/skill.h b/src/map/skill.h
index 28cb548d2..78829f17e 100644
--- a/src/map/skill.h
+++ b/src/map/skill.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _SKILL_H_
-#define _SKILL_H_
+#ifndef _MAP_SKILL_H_
+#define _MAP_SKILL_H_
#include "../common/mmo.h" // MAX_SKILL, struct square
#include "../common/db.h"
@@ -2015,4 +2015,4 @@ struct skill_interface *skill;
void skill_defaults(void);
-#endif /* _SKILL_H_ */
+#endif /* _MAP_SKILL_H_ */
diff --git a/src/map/status.c b/src/map/status.c
index 74b2571e1..4114bc859 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -2598,12 +2598,29 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
}
/* we've got combos to process */
- if( sd->combos.count ) {
- for( i = 0; i < sd->combos.count; i++ ) {
- script->run(sd->combos.bonus[i],0,sd->bl.id,0);
- if (!calculating) //Abort, script->run retriggered this.
- return 1;
+ for( i = 0; i < sd->combo_count; i++ ) {
+ struct item_combo *combo = itemdb->id2combo(sd->combos[i].id);
+ unsigned char j;
+
+ /**
+ * ensure combo usage is allowed at this location
+ **/
+ for(j = 0; j < combo->count; j++) {
+ for(k = 0; k < map->list[sd->bl.m].zone->disabled_items_count; k++) {
+ if( map->list[sd->bl.m].zone->disabled_items[k] == combo->nameid[j] ) {
+ break;
+ }
+ }
+ if( k != map->list[sd->bl.m].zone->disabled_items_count )
+ break;
}
+
+ if( j != combo->count )
+ continue;
+
+ script->run(sd->combos[i].bonus,0,sd->bl.id,0);
+ if (!calculating) //Abort, script->run retriggered this.
+ return 1;
}
//Store equipment script bonuses
@@ -5529,12 +5546,14 @@ short status_calc_aspd_rate(struct block_list *bl, struct status_change *sc, int
}
unsigned short status_calc_dmotion(struct block_list *bl, struct status_change *sc, int dmotion) {
+ // It has been confirmed on official servers that MvP mobs have no dmotion even without endure
+ if( bl->type == BL_MOB && (((TBL_MOB*)bl)->status.mode&MD_BOSS) )
+ return 0;
+
if( !sc || !sc->count || map_flag_gvg2(bl->m) || map->list[bl->m].flag.battleground )
return cap_value(dmotion,0,USHRT_MAX);
- /**
- * It has been confirmed on official servers that MvP mobs have no dmotion even without endure
- **/
- if( sc->data[SC_ENDURE] || ( bl->type == BL_MOB && (((TBL_MOB*)bl)->status.mode&MD_BOSS) ) )
+
+ if( sc->data[SC_ENDURE] )
return 0;
if( sc->data[SC_RUN] || sc->data[SC_WUGDASH] )
return 0;
@@ -9123,8 +9142,11 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
sce->val4 = val4;
if (tick >= 0)
sce->timer = timer->add(timer->gettick() + tick, status->change_timer, bl->id, type);
- else
+ else {
sce->timer = INVALID_TIMER; //Infinite duration
+ if( sd )
+ chrif->save_scdata_single(sd->status.account_id,sd->status.char_id,type,sce);
+ }
if (calc_flag)
status_calc_bl(bl,calc_flag);
@@ -9305,6 +9327,9 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
if (sce->timer != tid && tid != INVALID_TIMER)
return 0;
+ if( sd && sce->timer == INVALID_TIMER )
+ chrif->del_scdata_single(sd->status.account_id,sd->status.char_id,type);
+
if (tid == INVALID_TIMER) {
if (type == SC_ENDURE && sce->val4)
//Do not end infinite endure.
diff --git a/src/map/status.h b/src/map/status.h
index f319b1506..d3148b4e0 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _STATUS_H_
-#define _STATUS_H_
+#ifndef _MAP_STATUS_H_
+#define _MAP_STATUS_H_
#include "../common/mmo.h"
@@ -2012,4 +2012,4 @@ struct status_interface *status;
void status_defaults(void);
-#endif /* _STATUS_H_ */
+#endif /* _MAP_STATUS_H_ */
diff --git a/src/map/storage.h b/src/map/storage.h
index 8a10c9f3b..8f9f904f6 100644
--- a/src/map/storage.h
+++ b/src/map/storage.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _STORAGE_H_
-#define _STORAGE_H_
+#ifndef _MAP_STORAGE_H_
+#define _MAP_STORAGE_H_
struct storage_data;
struct guild_storage;
@@ -59,4 +59,4 @@ struct guild_storage_interface *gstorage;
void storage_defaults(void);
void gstorage_defaults(void);
-#endif /* _STORAGE_H_ */
+#endif /* _MAP_STORAGE_H_ */
diff --git a/src/map/trade.h b/src/map/trade.h
index d0b900504..f2c0d4622 100644
--- a/src/map/trade.h
+++ b/src/map/trade.h
@@ -2,10 +2,11 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _TRADE_H_
-#define _TRADE_H_
+#ifndef _MAP_TRADE_H_
+#define _MAP_TRADE_H_
//Max distance from traders to enable a trade to take place.
+//TODO: battle_config candidate?
#define TRADE_DISTANCE 2
struct map_session_data;
@@ -26,4 +27,4 @@ struct trade_interface *trade;
void trade_defaults(void);
-#endif /* _TRADE_H_ */
+#endif /* _MAP_TRADE_H_ */
diff --git a/src/map/unit.c b/src/map/unit.c
index 7b37be266..320649a6c 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -2363,11 +2363,11 @@ int unit_free(struct block_list *bl, clr_type clrtype) {
sd->st = NULL;
sd->npc_id = 0;
}
- if( sd->combos.count ) {
- aFree(sd->combos.bonus);
- aFree(sd->combos.id);
- sd->combos.count = 0;
+ if( sd->combos ) {
+ aFree(sd->combos);
+ sd->combos = NULL;
}
+ sd->combo_count = 0;
/* [Ind/Hercules] */
if( sd->sc_display_count ) {
for(i = 0; i < sd->sc_display_count; i++) {
diff --git a/src/map/unit.h b/src/map/unit.h
index a2d743875..33fa4e052 100644
--- a/src/map/unit.h
+++ b/src/map/unit.h
@@ -1,8 +1,9 @@
-// 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
-#ifndef _UNIT_H_
-#define _UNIT_H_
+#ifndef _MAP_UNIT_H_
+#define _MAP_UNIT_H_
//#include "map.h"
struct block_list;
@@ -125,4 +126,4 @@ struct unit_interface *unit;
void unit_defaults(void);
-#endif /* _UNIT_H_ */
+#endif /* _MAP_UNIT_H_ */
diff --git a/src/map/vending.h b/src/map/vending.h
index b760bf064..b2ba22955 100644
--- a/src/map/vending.h
+++ b/src/map/vending.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _VENDING_H_
-#define _VENDING_H_
+#ifndef _MAP_VENDING_H_
+#define _MAP_VENDING_H_
#include "../common/cbasetypes.h"
#include "../common/db.h"
@@ -35,4 +35,4 @@ struct vending_interface *vending;
void vending_defaults(void);
-#endif /* _VENDING_H_ */
+#endif /* _MAP_VENDING_H_ */