summaryrefslogtreecommitdiff
path: root/src/map/map.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/map.c')
-rw-r--r--src/map/map.c225
1 files changed, 126 insertions, 99 deletions
diff --git a/src/map/map.c b/src/map/map.c
index a423e6973..b254b6792 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -2,62 +2,66 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#include "../common/cbasetypes.h"
-#include "../common/core.h"
-#include "../common/timer.h"
-#include "../common/ers.h"
-#include "../common/grfio.h"
-#include "../common/malloc.h"
-#include "../common/socket.h" // WFIFO*()
-#include "../common/showmsg.h"
-#include "../common/nullpo.h"
-#include "../common/random.h"
-#include "../common/strlib.h"
-#include "../common/utils.h"
-#include "../common/conf.h"
-#include "../common/console.h"
-#include "../common/HPM.h"
+#define HERCULES_CORE
+#include "../config/core.h" // CELL_NOSTACK, CIRCULAR_AREA, CONSOLE_INPUT, DBPATH, RENEWAL
#include "map.h"
-#include "path.h"
+
+#include <math.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "HPMmap.h"
+#include "atcommand.h"
+#include "battle.h"
+#include "battleground.h"
+#include "chat.h"
#include "chrif.h"
#include "clif.h"
#include "duel.h"
+#include "elemental.h"
+#include "guild.h"
+#include "homunculus.h"
+#include "instance.h"
#include "intif.h"
+#include "irc-bot.h"
+#include "itemdb.h"
+#include "log.h"
+#include "mail.h"
+#include "mapreg.h"
+#include "mercenary.h"
+#include "mob.h"
#include "npc.h"
+#include "npc.h" // npc_setcells(), npc_unsetcells()
+#include "party.h"
+#include "path.h"
#include "pc.h"
+#include "pet.h"
+#include "quest.h"
+#include "script.h"
+#include "skill.h"
#include "status.h"
-#include "mob.h"
-#include "npc.h" // npc_setcells(), npc_unsetcells()
-#include "chat.h"
-#include "itemdb.h"
#include "storage.h"
-#include "skill.h"
#include "trade.h"
-#include "party.h"
#include "unit.h"
-#include "battle.h"
-#include "battleground.h"
-#include "quest.h"
-#include "script.h"
-#include "mapreg.h"
-#include "guild.h"
-#include "pet.h"
-#include "homunculus.h"
-#include "instance.h"
-#include "mercenary.h"
-#include "elemental.h"
-#include "atcommand.h"
-#include "log.h"
-#include "mail.h"
-#include "irc-bot.h"
-#include "HPMmap.h"
+#include "../common/HPM.h"
+#include "../common/cbasetypes.h"
+#include "../common/conf.h"
+#include "../common/console.h"
+#include "../common/core.h"
+#include "../common/ers.h"
+#include "../common/grfio.h"
+#include "../common/malloc.h"
+#include "../common/nullpo.h"
+#include "../common/random.h"
+#include "../common/showmsg.h"
+#include "../common/socket.h" // WFIFO*()
+#include "../common/strlib.h"
+#include "../common/timer.h"
+#include "../common/utils.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <math.h>
#ifndef _WIN32
#include <unistd.h>
#endif
@@ -163,31 +167,32 @@ int map_freeblock_timer(int tid, int64 tick, int id, intptr_t data) {
return 0;
}
-/*==========================================
- * These pair of functions update the counter of how many objects
- * lie on a tile.
- *------------------------------------------*/
-void map_addblcell(struct block_list *bl) {
+/**
+ * Updates the counter (cell.cell_bl) of how many objects are on a tile.
+ * @param add Whether the counter should be increased or decreased
+ **/
+void map_update_cell_bl( struct block_list *bl, bool increase ) {
#ifdef CELL_NOSTACK
+ int pos;
+
if( bl->m < 0 || bl->x < 0 || bl->x >= map->list[bl->m].xs
|| bl->y < 0 || bl->y >= map->list[bl->m].ys
|| !(bl->type&BL_CHAR) )
return;
- map->list[bl->m].cell[bl->x+bl->y*map->list[bl->m].xs].cell_bl++;
-#else
- return;
-#endif
-}
-void map_delblcell(struct block_list *bl) {
-#ifdef CELL_NOSTACK
- if( bl->m < 0 || bl->x < 0 || bl->x >= map->list[bl->m].xs
- || bl->y < 0 || bl->y >= map->list[bl->m].ys
- || !(bl->type&BL_CHAR) )
- map->list[bl->m].cell[bl->x+bl->y*map->list[bl->m].xs].cell_bl--;
-#else
- return;
+ // When reading from mapcache the cell isn't initialized
+ // TODO: Maybe start initializing cells when they're loaded instead of
+ // having to get them here? [Panikon]
+ if( map->list[bl->m].cell == (struct mapcell *)0xdeadbeaf )
+ map->cellfromcache(&map->list[bl->m]);
+
+ pos = bl->x + bl->y*map->list[bl->m].xs;
+ if( increase )
+ map->list[bl->m].cell[pos].cell_bl++;
+ else
+ map->list[bl->m].cell[pos].cell_bl--;
#endif
+ return;
}
/*==========================================
@@ -233,7 +238,7 @@ int map_addblock(struct block_list* bl)
}
#ifdef CELL_NOSTACK
- map->addblcell(bl);
+ map->update_cell_bl(bl, true);
#endif
return 0;
@@ -250,14 +255,14 @@ int map_delblock(struct block_list* bl)
// blocklist (2ways chainlist)
if (bl->prev == NULL) {
if (bl->next != NULL) {
- // can't delete block (already at the begining of the chain)
+ // can't delete block (already at the beginning of the chain)
ShowError("map_delblock error : bl->next!=NULL\n");
}
return 0;
}
#ifdef CELL_NOSTACK
- map->delblcell(bl);
+ map->update_cell_bl(bl, false);
#endif
pos = bl->x/BLOCK_SIZE+(bl->y/BLOCK_SIZE)*map->list[bl->m].bxs;
@@ -315,13 +320,13 @@ int map_moveblock(struct block_list *bl, int x1, int y1, int64 tick) {
if (moveblock) map->delblock(bl);
#ifdef CELL_NOSTACK
- else map->delblcell(bl);
+ else map->update_cell_bl(bl, false);
#endif
bl->x = x1;
bl->y = y1;
if (moveblock) map->addblock(bl);
#ifdef CELL_NOSTACK
- else map->addblcell(bl);
+ else map->update_cell_bl(bl, true);
#endif
if (bl->type&BL_CHAR) {
@@ -464,7 +469,7 @@ static int bl_vforeach(int (*func)(struct block_list*, va_list), int blockcount,
map->freeblock_lock();
for (i = blockcount; i < map->bl_list_count && returnCount < max; i++) {
- if (map->bl_list[i]->prev) { //func() may delete this bl_list[] slot, checking for prev ensures it wasnt queued for deletion.
+ if (map->bl_list[i]->prev) { //func() may delete this bl_list[] slot, checking for prev ensures it wasn't queued for deletion.
va_list argscopy;
va_copy(argscopy, args);
returnCount += func(map->bl_list[i], argscopy);
@@ -490,7 +495,7 @@ static int bl_vforeach(int (*func)(struct block_list*, va_list), int blockcount,
static int map_vforeachinmap(int (*func)(struct block_list*, va_list), int16 m, int type, va_list args) {
int i;
int returnCount = 0;
- int bsize;
+ int bsize;
va_list argscopy;
struct block_list *bl;
int blockcount = map->bl_list_count;
@@ -2033,7 +2038,7 @@ void map_foreachnpc(int (*func)(struct npc_data* nd, va_list args), ...) {
}
/// Applies func to everything in the db.
-/// Stops iteratin gif func returns -1.
+/// Stops iterating gif func returns -1.
void map_vforeachregen(int (*func)(struct block_list* bl, va_list args), va_list args) {
DBIterator* iter;
struct block_list* bl;
@@ -2053,7 +2058,7 @@ void map_vforeachregen(int (*func)(struct block_list* bl, va_list args), va_list
}
/// Applies func to everything in the db.
-/// Stops iteratin gif func returns -1.
+/// Stops iterating gif func returns -1.
/// @see map_vforeachregen
void map_foreachregen(int (*func)(struct block_list* bl, va_list args), ...) {
va_list args;
@@ -2517,8 +2522,13 @@ void map_cellfromcache(struct map_data *m) {
decode_zip(decode_buffer, &size, m->cellPos+sizeof(struct map_cache_map_info), info->len);
CREATE(m->cell, struct mapcell, size);
- for( xy = 0; xy < size; ++xy )
+ // Set cell properties
+ for( xy = 0; xy < size; ++xy ) {
m->cell[xy] = map->gat2cell(decode_buffer[xy]);
+#ifdef CELL_NOSTACK
+ m->cell[xy].cell_bl = 0;
+#endif
+ }
m->getcellp = map->getcellp;
m->setcell = map->setcell;
@@ -2846,6 +2856,7 @@ int map_eraseipport(unsigned short map_index, uint32 ip, uint16 port) {
* [Shinryo]: Init the mapcache
*------------------------------------------*/
char *map_init_mapcache(FILE *fp) {
+ struct map_cache_main_header header;
size_t size = 0;
char *buffer;
@@ -2866,6 +2877,21 @@ char *map_init_mapcache(FILE *fp) {
// Read file into buffer..
if(fread(buffer, sizeof(char), size, fp) != size) {
ShowError("map_init_mapcache: Could not read entire mapcache file\n");
+ aFree(buffer);
+ return NULL;
+ }
+
+ rewind(fp);
+
+ // Get main header to verify if data is corrupted
+ if( fread(&header, sizeof(header), 1, fp) != 1 ) {
+ ShowError("map_init_mapcache: Error obtaining main header!\n");
+ aFree(buffer);
+ return NULL;
+ }
+ if( GetULong((unsigned char *)&(header.file_size)) != size ) {
+ ShowError("map_init_mapcache: Map cache is corrupted!\n");
+ aFree(buffer);
return NULL;
}
@@ -3273,6 +3299,9 @@ int map_readgat (struct map_data* m)
type = 3; // Cell is 0 (walkable) but under water level, set to 3 (walkable water)
m->cell[xy] = map->gat2cell(type);
+#ifdef CELL_NOSTACK
+ m->cell[xy].cell_bl = 0;
+#endif
}
aFree(gat);
@@ -3636,6 +3665,8 @@ int inter_config_read(char *cfgName) {
strcpy(map->autotrade_merchants_db, w2);
else if(strcmpi(w1,"autotrade_data_db")==0)
strcpy(map->autotrade_data_db, w2);
+ else if(strcmpi(w1,"npc_market_data_db")==0)
+ strcpy(map->npc_market_data_db, w2);
/* sql log db */
else if(strcmpi(w1,"log_db_ip")==0)
strcpy(logs->db_ip, w2);
@@ -3765,10 +3796,9 @@ struct map_zone_data *map_merge_zone(struct map_zone_data *main, struct map_zone
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));
+ memcpy(zone->capped_skills[cursor], main->capped_skills[i], sizeof(struct map_zone_skill_damage_cap_entry));
}
for(i = 0; i < other->capped_skills_count; i++, cursor++ ) {
@@ -3826,7 +3856,7 @@ void map_zone_remove(int m) {
}
}
- npc->parse_mapflag(map->list[m].name,empty,flag,params,empty,empty,empty);
+ npc->parse_mapflag(map->list[m].name,empty,flag,params,empty,empty,empty, NULL);
aFree(map->list[m].zone_mf[k]);
map->list[m].zone_mf[k] = NULL;
}
@@ -4381,7 +4411,7 @@ bool map_zone_mf_cache(int m, char *flag, char *params) {
}
if( modifier[0] == '\0' || !( skill_id = skill->name2id(skill_name) ) || !skill->get_unit_id( skill->name2id(skill_name), 0) || atoi(modifier) < 1 || atoi(modifier) > USHRT_MAX ) {
- ;/* we dont mind it, the server will take care of it next. */
+ ;/* we don't mind it, the server will take care of it next. */
} else {
int idx = map->list[m].unit_count;
@@ -4414,7 +4444,7 @@ bool map_zone_mf_cache(int m, char *flag, char *params) {
}
if( modifier[0] == '\0' || !( skill_id = skill->name2id(skill_name) ) || atoi(modifier) < 1 || atoi(modifier) > USHRT_MAX ) {
- ;/* we dont mind it, the server will take care of it next. */
+ ;/* we don't mind it, the server will take care of it next. */
} else {
int idx = map->list[m].skill_count;
@@ -4558,7 +4588,7 @@ void map_zone_apply(int m, struct map_zone_data *zone, const char* start, const
if( map->zone_mf_cache(m,flag,params) )
continue;
- npc->parse_mapflag(map->list[m].name,empty,flag,params,start,buffer,filepath);
+ npc->parse_mapflag(map->list[m].name, empty, flag, params, start, buffer, filepath, NULL);
}
}
/* used on npc load and reload to apply all "Normal" and "PK Mode" zones */
@@ -4586,7 +4616,7 @@ void map_zone_init(void) {
if( map->list[j].zone == zone ) {
if( map->zone_mf_cache(j,flag,params) )
break;
- npc->parse_mapflag(map->list[j].name,empty,flag,params,empty,empty,empty);
+ npc->parse_mapflag(map->list[j].name, empty, flag, params, empty, empty, empty, NULL);
}
}
}
@@ -4608,7 +4638,7 @@ void map_zone_init(void) {
if( map->list[j].zone == zone ) {
if( map->zone_mf_cache(j,flag,params) )
break;
- npc->parse_mapflag(map->list[j].name,empty,flag,params,empty,empty,empty);
+ npc->parse_mapflag(map->list[j].name, empty, flag, params, empty, empty, empty, NULL);
}
}
}
@@ -4771,7 +4801,7 @@ void read_map_zone_db(void) {
--h;
continue;
}
- if( !map->zone_bl_type(libconfig->setting_get_string_elem(skills,h),&subtype) )/* we dont remove it from the three due to inheritance */
+ if( !map->zone_bl_type(libconfig->setting_get_string_elem(skills,h),&subtype) )/* we don't remove it from the three due to inheritance */
--disabled_skills_count;
}
/* all ok, process */
@@ -4809,7 +4839,7 @@ void read_map_zone_db(void) {
--h;
continue;
}
- if( !libconfig->setting_get_bool(item) )/* we dont remove it from the three due to inheritance */
+ if( !libconfig->setting_get_bool(item) )/* we don't remove it from the three due to inheritance */
--disabled_items_count;
}
/* all ok, process */
@@ -4854,7 +4884,7 @@ void read_map_zone_db(void) {
--h;
continue;
}
- if( !libconfig->setting_get_int(command) )/* we dont remove it from the three due to inheritance */
+ if( !libconfig->setting_get_int(command) )/* we don't remove it from the three due to inheritance */
--disabled_commands_count;
}
/* all ok, process */
@@ -4890,7 +4920,7 @@ void read_map_zone_db(void) {
--h;
continue;
}
- if( !map->zone_bl_type(libconfig->setting_get_string_elem(cap,1),&subtype) )/* we dont remove it from the three due to inheritance */
+ if( !map->zone_bl_type(libconfig->setting_get_string_elem(cap,1),&subtype) )/* we don't remove it from the three due to inheritance */
--capped_skills_count;
}
/* all ok, process */
@@ -5213,8 +5243,7 @@ int cleanup_db_sub(DBKey key, DBData *data, va_list va) {
/*==========================================
* map destructor
*------------------------------------------*/
-void do_final(void)
-{
+int do_final(void) {
int i;
struct map_session_data* sd;
struct s_mapiterator* iter;
@@ -5309,6 +5338,7 @@ void do_final(void)
HPM->event(HPET_POST_FINAL);
ShowStatus("Finished.\n");
+ return map->retval;
}
int map_abort_sub(struct map_session_data* sd, va_list ap) {
@@ -5373,9 +5403,6 @@ void map_helpscreen(bool do_exit)
* Map-Server Version Screen [MC Cameri]
*------------------------------------------------------*/
void map_versionscreen(bool do_exit) {
- const char *svn = get_svn_revision();
- const char *git = get_git_hash();
- ShowInfo(CL_WHITE"Hercules version: %s" CL_RESET"\n", git[0] != HERC_UNKNOWN_VER ? git : svn[0] != HERC_UNKNOWN_VER ? svn : "Unknown");
ShowInfo(CL_GREEN"Website/Forum:"CL_RESET"\thttp://hercules.ws/\n");
ShowInfo(CL_GREEN"IRC Channel:"CL_RESET"\tirc://irc.rizon.net/#Hercules\n");
ShowInfo("Open "CL_WHITE"readme.txt"CL_RESET" for more information.\n");
@@ -5468,8 +5495,8 @@ void map_cp_defaults(void) {
map->cpsd->bl.y = MAP_DEFAULT_Y;
map->cpsd->bl.m = map->mapname2mapid(MAP_DEFAULT);
- console->addCommand("gm:info",CPCMD_A(gm_position));
- console->addCommand("gm:use",CPCMD_A(gm_use));
+ console->input->addCommand("gm:info",CPCMD_A(gm_position));
+ console->input->addCommand("gm:use",CPCMD_A(gm_use));
#endif
}
/* Hercules Plugin Mananger */
@@ -5694,7 +5721,7 @@ int do_init(int argc, char *argv[])
char ip_str[16];
ip2str(sockt->addr_[0], ip_str);
- ShowWarning("Not all IP addresses in /conf/map-server.conf configured, autodetecting...\n");
+ ShowWarning("Not all IP addresses in /conf/map-server.conf configured, auto-detecting...\n");
if (sockt->naddr_ == 0)
ShowError("Unable to determine your IP address...\n");
@@ -5718,7 +5745,7 @@ int do_init(int argc, char *argv[])
map->id_db = idb_alloc(DB_OPT_BASE);
map->pc_db = idb_alloc(DB_OPT_BASE); //Added for reliable map->id2sd() use. [Skotlex]
- map->mobid_db = idb_alloc(DB_OPT_BASE); //Added to lower the load of the lazy mob ai. [Skotlex]
+ map->mobid_db = idb_alloc(DB_OPT_BASE); //Added to lower the load of the lazy mob AI. [Skotlex]
map->bossid_db = idb_alloc(DB_OPT_BASE); // Used for Convex Mirror quick MVP search
map->map_db = uidb_alloc(DB_OPT_BASE);
map->nick_db = idb_alloc(DB_OPT_BASE);
@@ -5777,7 +5804,7 @@ int do_init(int argc, char *argv[])
itemdb->init(minimal);
skill->init(minimal);
if (!minimal)
- map->read_zone_db();/* read after item and skill initalization */
+ map->read_zone_db();/* read after item and skill initialization */
mob->init(minimal);
pc->init(minimal);
status->init(minimal);
@@ -5798,7 +5825,7 @@ int do_init(int argc, char *argv[])
if (scriptcheck) {
bool failed = load_extras_count > 0 ? false : true;
for (i = 0; i < load_extras_count; i++) {
- if (npc->parsesrcfile(load_extras[i], false) != 0)
+ if (npc->parsesrcfile(load_extras[i], false) != EXIT_SUCCESS)
failed = true;
}
if (failed)
@@ -5816,7 +5843,7 @@ int do_init(int argc, char *argv[])
exit(EXIT_SUCCESS);
}
- npc->event_do_oninit(); // Init npcs (OnInit)
+ npc->event_do_oninit( false ); // Init npcs (OnInit)
npc->market_fromsql(); /* after OnInit */
if (battle_config.pk_mode)
@@ -5825,7 +5852,7 @@ int do_init(int argc, char *argv[])
Sql_HerculesUpdateCheck(map->mysql_handle);
#ifdef CONSOLE_INPUT
- console->setSQL(map->mysql_handle);
+ console->input->setSQL(map->mysql_handle);
#endif
ShowStatus("Server is '"CL_GREEN"ready"CL_RESET"' and listening on port '"CL_WHITE"%d"CL_RESET"'.\n\n", map->port);
@@ -5843,7 +5870,7 @@ int do_init(int argc, char *argv[])
}
/*=====================================
-* Default Functions : map.h
+* Default Functions : map.h
* Generated by HerculesInterfaceMaker
* created by Susu
*-------------------------------------*/
@@ -5853,6 +5880,7 @@ void map_defaults(void) {
/* */
map->minimal = false;
map->count = 0;
+ map->retval = EXIT_SUCCESS;
sprintf(map->db_path ,"db");
sprintf(map->help_txt ,"conf/help.txt");
@@ -6107,8 +6135,7 @@ void map_defaults(void) {
map->versionscreen = map_versionscreen;
map->arg_next_value = map_arg_next_value;
- map->addblcell = map_addblcell;
- map->delblcell = map_delblcell;
+ map->update_cell_bl = map_update_cell_bl;
map->get_new_bonus_id = map_get_new_bonus_id;