Cleaned up map data storage (#3347)
Follow up to a942853. Fixes #3336. Moved map_data storage to std::map container. Created map_getmapdata to obtain pointer to map_data. Got rid of MAX_MAP_PER_SERVER define. Resolved deletion of instances causing other instances to lose their intended map ID. Refactored warp suggestions Thanks to @teededung, @anacondaqq, @cydh and @Lemongrass3110!
This commit is contained in:
parent
62ac5be447
commit
584fcac43a
@ -4,6 +4,8 @@
|
||||
#ifndef _CHAR_HPP_
|
||||
#define _CHAR_HPP_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "../common/core.hpp" // CORE_ST_LAST
|
||||
#include "../common/mmo.hpp"
|
||||
#include "../common/msg_conf.hpp"
|
||||
@ -197,7 +199,7 @@ struct mmo_map_server {
|
||||
uint32 ip;
|
||||
uint16 port;
|
||||
int users;
|
||||
unsigned short map[MAX_MAP_PER_SERVER];
|
||||
std::vector<uint16> map;
|
||||
};
|
||||
extern struct mmo_map_server map_server[MAX_MAP_SERVERS];
|
||||
|
||||
|
@ -676,7 +676,7 @@ int chclif_parse_maplogin(int fd){
|
||||
map_server[i].ip = ntohl(RFIFOL(fd,54));
|
||||
map_server[i].port = ntohs(RFIFOW(fd,58));
|
||||
map_server[i].users = 0;
|
||||
memset(map_server[i].map, 0, sizeof(map_server[i].map));
|
||||
map_server[i].map = {};
|
||||
session[fd]->func_parse = chmapif_parse;
|
||||
session[fd]->flag.server = 1;
|
||||
realloc_fifo(fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
|
||||
|
@ -239,29 +239,27 @@ void chmapif_send_maps(int fd, int map_id, int count, unsigned char *mapbuf) {
|
||||
* @return : 0 not enough data received, 1 success
|
||||
*/
|
||||
int chmapif_parse_getmapname(int fd, int id){
|
||||
int i = 0, j = 0;
|
||||
int i = 0;
|
||||
unsigned char *mapbuf;
|
||||
|
||||
if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
|
||||
return 0;
|
||||
|
||||
//Retain what map-index that map-serv contains
|
||||
memset(map_server[id].map, 0, sizeof(map_server[id].map));
|
||||
for(i = 4; i < RFIFOW(fd,2); i += 4) {
|
||||
map_server[id].map[j] = RFIFOW(fd,i);
|
||||
j++;
|
||||
}
|
||||
map_server[id].map = {};
|
||||
for(i = 4; i < RFIFOW(fd,2); i += 4)
|
||||
map_server[id].map.push_back(RFIFOW(fd, i));
|
||||
|
||||
mapbuf = RFIFOP(fd,4);
|
||||
RFIFOSKIP(fd,RFIFOW(fd,2));
|
||||
|
||||
ShowStatus("Map-Server %d connected: %d maps, from IP %d.%d.%d.%d port %d.\n",
|
||||
id, j, CONVIP(map_server[id].ip), map_server[id].port);
|
||||
id, map_server[id].map.size(), CONVIP(map_server[id].ip), map_server[id].port);
|
||||
ShowStatus("Map-server %d loading complete.\n", id);
|
||||
|
||||
chmapif_send_misc(fd);
|
||||
chmapif_send_fame_list(fd); //Send fame list.
|
||||
chmapif_send_maps(fd, id, j, mapbuf);
|
||||
chmapif_send_maps(fd, id, map_server[id].map.size(), mapbuf);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -1515,7 +1513,7 @@ void do_init_chmapif(void){
|
||||
* @param id: id of map-serv (should be >0, FIXME)
|
||||
*/
|
||||
void chmapif_server_reset(int id){
|
||||
int i,j;
|
||||
int j = 0;
|
||||
unsigned char buf[16384];
|
||||
int fd = map_server[id].fd;
|
||||
DBMap* online_char_db = char_get_onlinedb();
|
||||
@ -1524,8 +1522,7 @@ void chmapif_server_reset(int id){
|
||||
WBUFW(buf,0) = 0x2b20;
|
||||
WBUFL(buf,4) = htonl(map_server[id].ip);
|
||||
WBUFW(buf,8) = htons(map_server[id].port);
|
||||
j = 0;
|
||||
for(i = 0; i < MAX_MAP_PER_SERVER; i++)
|
||||
for(uint16 i = 0; i < map_server[id].map.size(); i++)
|
||||
if (map_server[id].map[i])
|
||||
WBUFW(buf,10+(j++)*4) = map_server[id].map[i];
|
||||
if (j > 0) {
|
||||
|
@ -32,7 +32,6 @@
|
||||
#define MAX_HOTKEYS 38
|
||||
#endif
|
||||
|
||||
#define MAX_MAP_PER_SERVER 1500 /// Increased to allow creation of Instance Maps
|
||||
#define MAX_INVENTORY 100 ///Maximum items in player inventory
|
||||
/** 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.
|
||||
* Max value tested was 265 */
|
||||
|
@ -387,62 +387,95 @@ ACMD_FUNC(send)
|
||||
* @author Euphy
|
||||
*/
|
||||
static void warp_get_suggestions(struct map_session_data* sd, const char *name) {
|
||||
char buffer[512];
|
||||
int i, count = 0;
|
||||
|
||||
if (strlen(name) < 2)
|
||||
// Minimum length for suggestions is 2 characters
|
||||
if( strlen( name ) < 2 ){
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<const char*> suggestions;
|
||||
|
||||
suggestions.reserve( MAX_SUGGESTIONS );
|
||||
|
||||
// check for maps that contain string
|
||||
for( auto& pair : map ){
|
||||
struct map_data *mapdata = &pair.second;
|
||||
|
||||
// Prevent suggestion of instance mapnames
|
||||
if( mapdata->instance_id != 0 ){
|
||||
continue;
|
||||
}
|
||||
|
||||
if( strstr( mapdata->name, name ) != nullptr ){
|
||||
suggestions.push_back( mapdata->name );
|
||||
|
||||
if( suggestions.size() == MAX_SUGGESTIONS ){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if no maps found, search by edit distance
|
||||
if( suggestions.empty() ){
|
||||
// Levenshtein > 4 is bad
|
||||
const int LEVENSHTEIN_MAX = 4;
|
||||
|
||||
std::map<int, std::vector<const char*>> maps;
|
||||
|
||||
for( auto& pair : map ){
|
||||
// Prevent suggestion of instance mapnames
|
||||
if( pair.second.instance_id != 0 ){
|
||||
continue;
|
||||
}
|
||||
|
||||
// Calculate the levenshtein distance of the two strings
|
||||
int distance = levenshtein( pair.second.name, name );
|
||||
|
||||
// Check if it is above the maximum defined distance
|
||||
if( distance > LEVENSHTEIN_MAX ){
|
||||
continue;
|
||||
}
|
||||
|
||||
std::vector<const char*>& vector = maps[distance];
|
||||
|
||||
// Do not add more entries than required
|
||||
if( vector.size() == MAX_SUGGESTIONS ){
|
||||
continue;
|
||||
}
|
||||
|
||||
vector.push_back( pair.second.name );
|
||||
}
|
||||
|
||||
for( int distance = 0; distance <= LEVENSHTEIN_MAX; distance++ ){
|
||||
std::vector<const char*>& vector = maps[distance];
|
||||
|
||||
for( const char* found_map : vector ){
|
||||
suggestions.push_back( found_map );
|
||||
|
||||
if( suggestions.size() == MAX_SUGGESTIONS ){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( suggestions.size() == MAX_SUGGESTIONS ){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If no suggestion could be made, do not output anything at all
|
||||
if( suggestions.empty() ){
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[CHAT_SIZE_MAX];
|
||||
|
||||
// build the suggestion string
|
||||
strcpy(buffer, msg_txt(sd, 205)); // Maybe you meant:
|
||||
strcat(buffer, "\n");
|
||||
|
||||
// check for maps that contain string
|
||||
for (i = 0; i < MAX_MAP_PER_SERVER; i++) {
|
||||
if (count < MAX_SUGGESTIONS && strstr(map[i].name, name) != NULL) {
|
||||
strcat(buffer, map[i].name);
|
||||
strcat(buffer, " ");
|
||||
if (++count >= MAX_SUGGESTIONS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if no maps found, search by edit distance
|
||||
if (!count) {
|
||||
unsigned int distance[MAX_MAP_PER_SERVER][2];
|
||||
int j;
|
||||
|
||||
// calculate Levenshtein distance for all maps
|
||||
for (i = 0; i < MAX_MAP_PER_SERVER; i++) {
|
||||
if (strlen(map[i].name) < 4) // invalid map name?
|
||||
distance[i][0] = INT_MAX;
|
||||
else {
|
||||
distance[i][0] = levenshtein(map[i].name, name);
|
||||
distance[i][1] = i;
|
||||
}
|
||||
}
|
||||
|
||||
// selection sort elements as needed
|
||||
count = min(MAX_SUGGESTIONS, 5); // results past 5 aren't worth showing
|
||||
for (i = 0; i < count; i++) {
|
||||
int min = i;
|
||||
for (j = i+1; j < MAX_MAP_PER_SERVER; j++) {
|
||||
if (distance[j][0] < distance[min][0])
|
||||
min = j;
|
||||
}
|
||||
|
||||
// print map name
|
||||
if (distance[min][0] > 4) { // awful results, don't bother
|
||||
if (!i) return;
|
||||
break;
|
||||
}
|
||||
strcat(buffer, map[distance[min][1]].name);
|
||||
strcat(buffer, " ");
|
||||
|
||||
// swap elements
|
||||
SWAP(distance[i][0], distance[min][0]);
|
||||
SWAP(distance[i][1], distance[min][1]);
|
||||
}
|
||||
for( const char* suggestion : suggestions ){
|
||||
strcat(buffer, suggestion);
|
||||
strcat(buffer, " ");
|
||||
}
|
||||
|
||||
clif_displaymessage(sd->fd, buffer);
|
||||
@ -709,12 +742,14 @@ ACMD_FUNC(who) {
|
||||
else
|
||||
StringBuf_Printf(&buf, msg_txt(sd,30), count); // %d players found.
|
||||
} else {
|
||||
struct map_data *mapdata = map_getmapdata(map_id);
|
||||
|
||||
if (count == 0)
|
||||
StringBuf_Printf(&buf, msg_txt(sd,54), map[map_id].name); // No player found in map '%s'.
|
||||
StringBuf_Printf(&buf, msg_txt(sd,54), mapdata->name); // No player found in map '%s'.
|
||||
else if (count == 1)
|
||||
StringBuf_Printf(&buf, msg_txt(sd,55), map[map_id].name); // 1 player found in map '%s'.
|
||||
StringBuf_Printf(&buf, msg_txt(sd,55), mapdata->name); // 1 player found in map '%s'.
|
||||
else
|
||||
StringBuf_Printf(&buf, msg_txt(sd,56), count, map[map_id].name); // %d players found in map '%s'.
|
||||
StringBuf_Printf(&buf, msg_txt(sd,56), count, mapdata->name); // %d players found in map '%s'.
|
||||
}
|
||||
clif_displaymessage(fd, StringBuf_Value(&buf));
|
||||
StringBuf_Destroy(&buf);
|
||||
@ -814,7 +849,7 @@ ACMD_FUNC(save)
|
||||
{
|
||||
nullpo_retr(-1, sd);
|
||||
|
||||
if( map[sd->bl.m].instance_id ) {
|
||||
if( map_getmapdata(sd->bl.m)->instance_id ) {
|
||||
clif_displaymessage(fd, msg_txt(sd,383)); // You cannot create a savepoint in an instance.
|
||||
return 1;
|
||||
}
|
||||
@ -995,7 +1030,7 @@ ACMD_FUNC(hide)
|
||||
clif_displaymessage(fd, msg_txt(sd,10)); // Invisible: Off
|
||||
|
||||
// increment the number of pvp players on the map
|
||||
map[sd->bl.m].users_pvp++;
|
||||
map_getmapdata(sd->bl.m)->users_pvp++;
|
||||
|
||||
if( !battle_config.pk_mode && map_getmapflag(sd->bl.m, MF_PVP) && !map_getmapflag(sd->bl.m, MF_PVP_NOCALCRANK) )
|
||||
{// register the player for ranking calculations
|
||||
@ -1009,7 +1044,7 @@ ACMD_FUNC(hide)
|
||||
clif_displaymessage(fd, msg_txt(sd,11)); // Invisible: On
|
||||
|
||||
// decrement the number of pvp players on the map
|
||||
map[sd->bl.m].users_pvp--;
|
||||
map_getmapdata(sd->bl.m)->users_pvp--;
|
||||
|
||||
if( map_getmapflag(sd->bl.m, MF_PVP) && !map_getmapflag(sd->bl.m, MF_PVP_NOCALCRANK) && sd->pvp_timer != INVALID_TIMER )
|
||||
{// unregister the player for ranking
|
||||
@ -2411,7 +2446,7 @@ ACMD_FUNC(gat)
|
||||
|
||||
for (y = 2; y >= -2; y--) {
|
||||
sprintf(atcmd_output, "%s (x= %d, y= %d) %02X %02X %02X %02X %02X",
|
||||
map[sd->bl.m].name, sd->bl.x - 2, sd->bl.y + y,
|
||||
map_getmapdata(sd->bl.m)->name, sd->bl.x - 2, sd->bl.y + y,
|
||||
map_getcell(sd->bl.m, sd->bl.x - 2, sd->bl.y + y, CELL_GETTYPE),
|
||||
map_getcell(sd->bl.m, sd->bl.x - 1, sd->bl.y + y, CELL_GETTYPE),
|
||||
map_getcell(sd->bl.m, sd->bl.x, sd->bl.y + y, CELL_GETTYPE),
|
||||
@ -4033,13 +4068,15 @@ ACMD_FUNC(mapinfo) {
|
||||
}
|
||||
mapit_free(iter);
|
||||
|
||||
sprintf(atcmd_output, msg_txt(sd,1040), mapname, map[m_id].users, map[m_id].npc_num, chat_num, vend_num); // Map: %s | Players: %d | NPCs: %d | Chats: %d | Vendings: %d
|
||||
struct map_data *mapdata = map_getmapdata(m_id);
|
||||
|
||||
sprintf(atcmd_output, msg_txt(sd,1040), mapname, mapdata->users, mapdata->npc_num, chat_num, vend_num); // Map: %s | Players: %d | NPCs: %d | Chats: %d | Vendings: %d
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
clif_displaymessage(fd, msg_txt(sd,1041)); // ------ Map Flags ------
|
||||
if (map_getmapflag(m_id, MF_TOWN))
|
||||
clif_displaymessage(fd, msg_txt(sd,1042)); // Town Map
|
||||
if (map_getmapflag(m_id, MF_RESTRICTED)){
|
||||
sprintf(atcmd_output, " Restricted (zone %d)",map[m_id].zone);
|
||||
sprintf(atcmd_output, " Restricted (zone %d)",mapdata->zone);
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
}
|
||||
|
||||
@ -4066,17 +4103,17 @@ ACMD_FUNC(mapinfo) {
|
||||
,(args.flag_val = SKILLDMG_OTHER && map_getmapflag_sub(m_id, MF_SKILL_DAMAGE, &args))
|
||||
,(args.flag_val = SKILLDMG_CASTER && map_getmapflag_sub(m_id, MF_SKILL_DAMAGE, &args)));
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
if (map[m_id].skill_damage.size()) {
|
||||
if (mapdata->skill_damage.size()) {
|
||||
clif_displaymessage(fd," > [Map Skill] Name : Player, Monster, Boss Monster, Other | Caster");
|
||||
for (int j = 0; j < map[m_id].skill_damage.size(); j++) {
|
||||
for (int j = 0; j < mapdata->skill_damage.size(); j++) {
|
||||
sprintf(atcmd_output," %d. %s : %d%%, %d%%, %d%%, %d%% | %d"
|
||||
,j+1
|
||||
,skill_get_name(map[m_id].skill_damage[j].skill_id)
|
||||
,map[m_id].skill_damage[j].rate[SKILLDMG_PC]
|
||||
,map[m_id].skill_damage[j].rate[SKILLDMG_MOB]
|
||||
,map[m_id].skill_damage[j].rate[SKILLDMG_BOSS]
|
||||
,map[m_id].skill_damage[j].rate[SKILLDMG_OTHER]
|
||||
,map[m_id].skill_damage[j].caster);
|
||||
,skill_get_name(mapdata->skill_damage[j].skill_id)
|
||||
,mapdata->skill_damage[j].rate[SKILLDMG_PC]
|
||||
,mapdata->skill_damage[j].rate[SKILLDMG_MOB]
|
||||
,mapdata->skill_damage[j].rate[SKILLDMG_BOSS]
|
||||
,mapdata->skill_damage[j].rate[SKILLDMG_OTHER]
|
||||
,mapdata->skill_damage[j].caster);
|
||||
clif_displaymessage(fd,atcmd_output);
|
||||
}
|
||||
}
|
||||
@ -4132,15 +4169,15 @@ ACMD_FUNC(mapinfo) {
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
|
||||
if (map_getmapflag(m_id, MF_NOSAVE)) {
|
||||
if (!map[m_id].save.map)
|
||||
if (!mapdata->save.map)
|
||||
clif_displaymessage(fd, msg_txt(sd,1068)); // No Save (Return to last Save Point)
|
||||
else if (map[m_id].save.x == -1 || map[m_id].save.y == -1 ) {
|
||||
sprintf(atcmd_output, msg_txt(sd,1069), mapindex_id2name(map[m_id].save.map)); // No Save, Save Point: %s,Random
|
||||
else if (mapdata->save.x == -1 || mapdata->save.y == -1 ) {
|
||||
sprintf(atcmd_output, msg_txt(sd,1069), mapindex_id2name(mapdata->save.map)); // No Save, Save Point: %s,Random
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
}
|
||||
else {
|
||||
sprintf(atcmd_output, msg_txt(sd,1070), // No Save, Save Point: %s,%d,%d
|
||||
mapindex_id2name(map[m_id].save.map),map[m_id].save.x,map[m_id].save.y);
|
||||
mapindex_id2name(mapdata->save.map),mapdata->save.x,mapdata->save.y);
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
}
|
||||
}
|
||||
@ -4239,9 +4276,9 @@ ACMD_FUNC(mapinfo) {
|
||||
break;
|
||||
case 2:
|
||||
clif_displaymessage(fd, msg_txt(sd,482)); // ----- NPCs in Map -----
|
||||
for (i = 0; i < map[m_id].npc_num;)
|
||||
for (i = 0; i < mapdata->npc_num;)
|
||||
{
|
||||
struct npc_data *nd = map[m_id].npc[i];
|
||||
struct npc_data *nd = mapdata->npc[i];
|
||||
switch(nd->ud.dir) {
|
||||
case DIR_NORTH: strcpy(direction, msg_txt(sd,491)); break; // North
|
||||
case DIR_NORTHWEST: strcpy(direction, msg_txt(sd,492)); break; // North West
|
||||
@ -7861,7 +7898,7 @@ ACMD_FUNC(whereis)
|
||||
int16 mapid = map_mapindex2mapid(spawn.mapindex);
|
||||
if (mapid < 0)
|
||||
continue;
|
||||
snprintf(atcmd_output, sizeof atcmd_output, "%s (%d)", map[mapid].name, spawn.qty);
|
||||
snprintf(atcmd_output, sizeof atcmd_output, "%s (%d)", map_getmapdata(mapid)->name, spawn.qty);
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
}
|
||||
}
|
||||
|
@ -2199,7 +2199,7 @@ static int battle_skill_damage_skill(struct block_list *src, struct block_list *
|
||||
(damage->map&4 && map_flag_gvg2(m)) ||
|
||||
(damage->map&8 && map_getmapflag(m, MF_BATTLEGROUND)) ||
|
||||
(damage->map&16 && map_getmapflag_sub(m, MF_SKILL_DAMAGE, &args)) ||
|
||||
(map_getmapflag(m, MF_RESTRICTED) && damage->map&(8*map[m].zone)))
|
||||
(map_getmapflag(m, MF_RESTRICTED) && damage->map&(8*map_getmapdata(m)->zone)))
|
||||
{
|
||||
return damage->rate[battle_skill_damage_type(target)];
|
||||
}
|
||||
@ -2216,24 +2216,24 @@ static int battle_skill_damage_skill(struct block_list *src, struct block_list *
|
||||
*/
|
||||
static int battle_skill_damage_map(struct block_list *src, struct block_list *target, uint16 skill_id) {
|
||||
int rate = 0;
|
||||
struct map_data *mapd = &map[src->m];
|
||||
struct map_data *mapdata = map_getmapdata(src->m);
|
||||
union u_mapflag_args args = {};
|
||||
|
||||
args.flag_val = SKILLDMG_MAX; // Check if it's enabled first
|
||||
if (!mapd || !map_getmapflag_sub(src->m, MF_SKILL_DAMAGE, &args))
|
||||
if (!mapdata || !map_getmapflag_sub(src->m, MF_SKILL_DAMAGE, &args))
|
||||
return 0;
|
||||
|
||||
// Damage rate for all skills at this map
|
||||
if (mapd->damage_adjust.caster&src->type)
|
||||
rate = mapd->damage_adjust.rate[battle_skill_damage_type(target)];
|
||||
if (mapdata->damage_adjust.caster&src->type)
|
||||
rate = mapdata->damage_adjust.rate[battle_skill_damage_type(target)];
|
||||
|
||||
if (mapd->skill_damage.empty())
|
||||
if (mapdata->skill_damage.empty())
|
||||
return rate;
|
||||
|
||||
// Damage rate for specified skill at this map
|
||||
for (int i = 0; i < mapd->skill_damage.size(); i++) {
|
||||
if (mapd->skill_damage[i].skill_id == skill_id && mapd->skill_damage[i].caster&src->type)
|
||||
rate += mapd->skill_damage[i].rate[battle_skill_damage_type(target)];
|
||||
for (int i = 0; i < mapdata->skill_damage.size(); i++) {
|
||||
if (mapdata->skill_damage[i].skill_id == skill_id && mapdata->skill_damage[i].caster&src->type)
|
||||
rate += mapdata->skill_damage[i].rate[battle_skill_damage_type(target)];
|
||||
}
|
||||
return rate;
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ int8 buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned cha
|
||||
|
||||
if( Sql_Query( mmysql_handle, "INSERT INTO `%s`(`id`, `account_id`, `char_id`, `sex`, `map`, `x`, `y`, `title`, `limit`, `autotrade`, `body_direction`, `head_direction`, `sit`) "
|
||||
"VALUES( %d, %d, %d, '%c', '%s', %d, %d, '%s', %d, %d, '%d', '%d', '%d' );",
|
||||
buyingstores_table, sd->buyer_id, sd->status.account_id, sd->status.char_id, sd->status.sex == 0 ? 'F' : 'M', map[sd->bl.m].name, sd->bl.x, sd->bl.y, message_sql, sd->buyingstore.zenylimit, sd->state.autotrade, at ? at->dir : sd->ud.dir, at ? at->head_dir : sd->head_dir, at ? at->sit : pc_issit(sd) ) != SQL_SUCCESS ){
|
||||
buyingstores_table, sd->buyer_id, sd->status.account_id, sd->status.char_id, sd->status.sex == 0 ? 'F' : 'M', map_getmapdata(sd->bl.m)->name, sd->bl.x, sd->bl.y, message_sql, sd->buyingstore.zenylimit, sd->state.autotrade, at ? at->dir : sd->ud.dir, at ? at->head_dir : sd->head_dir, at ? at->sit : pc_issit(sd) ) != SQL_SUCCESS ){
|
||||
Sql_ShowDebug(mmysql_handle);
|
||||
}
|
||||
|
||||
|
@ -163,7 +163,7 @@ int channel_delete(struct Channel *channel, bool force) {
|
||||
channel->group_count = 0;
|
||||
switch(channel->type){
|
||||
case CHAN_TYPE_MAP:
|
||||
map[channel->m].channel = NULL;
|
||||
map_getmapdata(channel->m)->channel = NULL;
|
||||
aFree(channel);
|
||||
break;
|
||||
case CHAN_TYPE_ALLY: {
|
||||
@ -251,16 +251,18 @@ int channel_mjoin(struct map_session_data *sd) {
|
||||
char mout[60];
|
||||
if(!sd) return -1;
|
||||
|
||||
if( !map[sd->bl.m].channel ) {
|
||||
map[sd->bl.m].channel = channel_create_simple(NULL,NULL,CHAN_TYPE_MAP,sd->bl.m);
|
||||
struct map_data *mapdata = map_getmapdata(sd->bl.m);
|
||||
|
||||
if( !mapdata->channel ) {
|
||||
mapdata->channel = channel_create_simple(NULL,NULL,CHAN_TYPE_MAP,sd->bl.m);
|
||||
}
|
||||
|
||||
if( map[sd->bl.m].channel->opt & CHAN_OPT_ANNOUNCE_SELF ) {
|
||||
sprintf(mout, msg_txt(sd,1435),map[sd->bl.m].channel->name,map[sd->bl.m].name); // You're now in the '#%s' channel for '%s'.
|
||||
if( mapdata->channel->opt & CHAN_OPT_ANNOUNCE_SELF ) {
|
||||
sprintf(mout, msg_txt(sd,1435),mapdata->channel->name,mapdata->name); // You're now in the '#%s' channel for '%s'.
|
||||
clif_messagecolor(&sd->bl, color_table[COLOR_LIGHT_GREEN], mout, false, SELF);
|
||||
}
|
||||
|
||||
return channel_join(map[sd->bl.m].channel,sd);
|
||||
return channel_join(mapdata->channel,sd);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -410,8 +412,11 @@ int channel_pcquit(struct map_session_data *sd, int type){
|
||||
}
|
||||
}
|
||||
}
|
||||
if(type&4 && channel_config.map_tmpl.name[0] && channel_haspc(map[sd->bl.m].channel,sd)==1){ //quit map chan
|
||||
channel_clean(map[sd->bl.m].channel,sd,0);
|
||||
|
||||
struct map_data *mapdata = map_getmapdata(sd->bl.m);
|
||||
|
||||
if(type&4 && channel_config.map_tmpl.name[0] && channel_haspc(mapdata->channel,sd)==1){ //quit map chan
|
||||
channel_clean(mapdata->channel,sd,0);
|
||||
}
|
||||
if(type&8 && sd->channel_count ) { //quit all chan
|
||||
uint8 count = sd->channel_count;
|
||||
@ -498,17 +503,20 @@ int channel_chk(char *chname, char *chpass, int type){
|
||||
struct Channel* channel_name2channel(char *chname, struct map_session_data *sd, int flag){
|
||||
if(channel_chk(chname, NULL, 1))
|
||||
return NULL;
|
||||
|
||||
struct map_data *mapdata = map_getmapdata(sd->bl.m);
|
||||
|
||||
if(sd && strcmpi(chname + 1,channel_config.map_tmpl.name) == 0){
|
||||
if(flag&1 && !map[sd->bl.m].channel)
|
||||
map[sd->bl.m].channel = channel_create_simple(NULL,NULL,CHAN_TYPE_MAP,sd->bl.m);
|
||||
if(flag&2 && channel_pc_haschan(sd,map[sd->bl.m].channel) < 1)
|
||||
if(flag&1 && !mapdata->channel)
|
||||
mapdata->channel = channel_create_simple(NULL,NULL,CHAN_TYPE_MAP,sd->bl.m);
|
||||
if(flag&2 && channel_pc_haschan(sd,mapdata->channel) < 1)
|
||||
channel_mjoin(sd);
|
||||
return map[sd->bl.m].channel;
|
||||
return mapdata->channel;
|
||||
}
|
||||
else if(sd && (strcmpi(chname + 1,channel_config.ally_tmpl.name) == 0) && sd->guild){
|
||||
if(flag&1 && !sd->guild->channel)
|
||||
sd->guild->channel = channel_create_simple(NULL,NULL,CHAN_TYPE_ALLY,sd->guild->guild_id);
|
||||
if(flag&2 && channel_pc_haschan(sd,map[sd->bl.m].channel) < 1)
|
||||
if(flag&2 && channel_pc_haschan(sd,mapdata->channel) < 1)
|
||||
channel_gjoin(sd,3);
|
||||
return sd->guild->channel;
|
||||
}
|
||||
@ -610,10 +618,11 @@ int channel_display_list(struct map_session_data *sd, const char *options){
|
||||
bool has_perm = pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ? true : false;
|
||||
struct Channel *channel;
|
||||
char output[CHAT_SIZE_MAX];
|
||||
struct map_data *mapdata = map_getmapdata(sd->bl.m);
|
||||
|
||||
clif_displaymessage(sd->fd, msg_txt(sd,1410)); // ---- Public Channels ----
|
||||
if( channel_config.map_tmpl.name[0] && map[sd->bl.m].channel ) {
|
||||
sprintf(output, msg_txt(sd,1409), map[sd->bl.m].channel->name, db_size(map[sd->bl.m].channel->users));// - #%s (%d users)
|
||||
if( channel_config.map_tmpl.name[0] && mapdata->channel ) {
|
||||
sprintf(output, msg_txt(sd,1409), mapdata->channel->name, db_size(mapdata->channel->users));// - #%s (%d users)
|
||||
clif_displaymessage(sd->fd, output);
|
||||
}
|
||||
if( channel_config.ally_tmpl.name[0] && sd->status.guild_id ) {
|
||||
|
@ -341,7 +341,7 @@ int chrif_save(struct map_session_data *sd, int flag) {
|
||||
WFIFOB(char_fd,12) = (flag&CSAVE_QUIT) ? 1 : 0; //Flag to tell char-server this character is quitting.
|
||||
|
||||
// If the user is on a instance map, we have to fake his current position
|
||||
if( map[sd->bl.m].instance_id ){
|
||||
if( map_getmapdata(sd->bl.m)->instance_id ){
|
||||
struct mmo_charstatus status;
|
||||
|
||||
// Copy the whole status
|
||||
@ -395,17 +395,18 @@ int chrif_connect(int fd) {
|
||||
|
||||
// sends maps to char-server
|
||||
int chrif_sendmap(int fd) {
|
||||
int i;
|
||||
|
||||
int i = 0, size = 4 + map.size() * 4;
|
||||
ShowStatus("Sending maps to char server...\n");
|
||||
|
||||
// Sending normal maps, not instances
|
||||
WFIFOHEAD(fd, 4 + map.size() * 4);
|
||||
WFIFOHEAD(fd, size);
|
||||
WFIFOW(fd,0) = 0x2afa;
|
||||
for(i = 0; i < map.size(); i++)
|
||||
WFIFOW(fd,4+i*4) = map[i].index;
|
||||
WFIFOW(fd,2) = 4 + i * 4;
|
||||
WFIFOSET(fd,WFIFOW(fd,2));
|
||||
WFIFOW(fd,2) = size;
|
||||
for( auto& pair : map ){
|
||||
WFIFOW(fd,4+i*4) = pair.second.index;
|
||||
i++;
|
||||
}
|
||||
WFIFOSET(fd,size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -3404,7 +3404,7 @@ void clif_updatestatus(struct map_session_data *sd,int type)
|
||||
}
|
||||
break;
|
||||
case SP_HP:
|
||||
if( map[sd->bl.m].hpmeter_visible ){
|
||||
if( map_getmapdata(sd->bl.m)->hpmeter_visible ){
|
||||
clif_hpmeter(sd);
|
||||
}
|
||||
if( !battle_config.party_hp_mode && sd->status.party_id ){
|
||||
@ -10324,10 +10324,12 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
|
||||
pc_setinvincibletimer(sd,battle_config.pc_invincible_time);
|
||||
}
|
||||
|
||||
if( map[sd->bl.m].users++ == 0 && battle_config.dynamic_mobs )
|
||||
struct map_data *mapdata = map_getmapdata(sd->bl.m);
|
||||
|
||||
if( mapdata->users++ == 0 && battle_config.dynamic_mobs )
|
||||
map_spawnmobs(sd->bl.m);
|
||||
if( !pc_isinvisible(sd) ) { // increment the number of pvp players on the map
|
||||
map[sd->bl.m].users_pvp++;
|
||||
mapdata->users_pvp++;
|
||||
}
|
||||
sd->state.debug_remove_map = 0; // temporary state to track double remove_map's [FlavioJS]
|
||||
|
||||
@ -10515,9 +10517,10 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
|
||||
guild_notice = false; // Do not display it twice
|
||||
}
|
||||
|
||||
if( (battle_config.bg_flee_penalty != 100 || battle_config.gvg_flee_penalty != 100) &&
|
||||
(map_flag_gvg(sd->state.pmap) || map_flag_gvg(sd->bl.m) || map_getmapflag(sd->state.pmap, MF_BATTLEGROUND) || map_getmapflag(sd->bl.m, MF_BATTLEGROUND)) )
|
||||
status_calc_bl(&sd->bl, SCB_FLEE); //Refresh flee penalty
|
||||
if (battle_config.bg_flee_penalty != 100 || battle_config.gvg_flee_penalty != 100) {
|
||||
if ((sd->state.pmap != 0 && map_getmapdata(sd->state.pmap) != nullptr && (map_flag_gvg(sd->state.pmap) || map_getmapflag(sd->state.pmap, MF_BATTLEGROUND))) || (mapdata != nullptr && (map_flag_gvg(sd->bl.m) || map_getmapflag(sd->bl.m, MF_BATTLEGROUND))))
|
||||
status_calc_bl(&sd->bl, SCB_FLEE); //Refresh flee penalty
|
||||
}
|
||||
|
||||
if( night_flag && map_getmapflag(sd->bl.m, MF_NIGHTENABLED) )
|
||||
{ //Display night.
|
||||
@ -10548,7 +10551,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
|
||||
}
|
||||
|
||||
if( pc_has_permission(sd,PC_PERM_VIEW_HPMETER) ) {
|
||||
map[sd->bl.m].hpmeter_visible++;
|
||||
mapdata->hpmeter_visible++;
|
||||
sd->state.hpmeter_visible = 1;
|
||||
}
|
||||
|
||||
@ -10569,7 +10572,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
|
||||
#endif
|
||||
|
||||
// Instances do not need their own channels
|
||||
if( channel_config.map_tmpl.name[0] && (channel_config.map_tmpl.opt&CHAN_OPT_AUTOJOIN) && !map_getmapflag(sd->bl.m,MF_NOMAPCHANNELAUTOJOIN) && !map[sd->bl.m].instance_id )
|
||||
if( channel_config.map_tmpl.name[0] && (channel_config.map_tmpl.opt&CHAN_OPT_AUTOJOIN) && !map_getmapflag(sd->bl.m,MF_NOMAPCHANNELAUTOJOIN) && !mapdata->instance_id )
|
||||
channel_mjoin(sd); //join new map
|
||||
|
||||
clif_pk_mode_message(sd);
|
||||
@ -17299,14 +17302,15 @@ void clif_bg_updatescore(int16 m)
|
||||
{
|
||||
struct block_list bl;
|
||||
unsigned char buf[6];
|
||||
struct map_data *mapdata = map_getmapdata(m);
|
||||
|
||||
bl.id = 0;
|
||||
bl.type = BL_NUL;
|
||||
bl.m = m;
|
||||
|
||||
WBUFW(buf,0) = 0x2de;
|
||||
WBUFW(buf,2) = map[m].bgscore_lion;
|
||||
WBUFW(buf,4) = map[m].bgscore_eagle;
|
||||
WBUFW(buf,2) = mapdata->bgscore_lion;
|
||||
WBUFW(buf,4) = mapdata->bgscore_eagle;
|
||||
clif_send(buf,packet_len(0x2de),&bl,ALL_SAMEMAP);
|
||||
}
|
||||
|
||||
@ -17316,10 +17320,12 @@ void clif_bg_updatescore_single(struct map_session_data *sd)
|
||||
nullpo_retv(sd);
|
||||
fd = sd->fd;
|
||||
|
||||
struct map_data *mapdata = map_getmapdata(sd->bl.m);
|
||||
|
||||
WFIFOHEAD(fd,packet_len(0x2de));
|
||||
WFIFOW(fd,0) = 0x2de;
|
||||
WFIFOW(fd,2) = map[sd->bl.m].bgscore_lion;
|
||||
WFIFOW(fd,4) = map[sd->bl.m].bgscore_eagle;
|
||||
WFIFOW(fd,2) = mapdata->bgscore_lion;
|
||||
WFIFOW(fd,4) = mapdata->bgscore_eagle;
|
||||
WFIFOSET(fd,packet_len(0x2de));
|
||||
}
|
||||
|
||||
|
@ -879,11 +879,11 @@ int guild_member_withdraw(int guild_id, uint32 account_id, uint32 char_id, int f
|
||||
sd->guild_emblem_id = 0;
|
||||
|
||||
if (g->instance_id) {
|
||||
int16 m = sd->bl.m;
|
||||
struct map_data *mapdata = map_getmapdata(sd->bl.m);
|
||||
|
||||
if (map[m].instance_id) { // User was on the instance map
|
||||
if (map[m].save.map)
|
||||
pc_setpos(sd, map[m].save.map, map[m].save.x, map[m].save.y, CLR_TELEPORT);
|
||||
if (mapdata->instance_id) { // User was on the instance map
|
||||
if (mapdata->save.map)
|
||||
pc_setpos(sd, mapdata->save.map, mapdata->save.x, mapdata->save.y, CLR_TELEPORT);
|
||||
else
|
||||
pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT);
|
||||
}
|
||||
|
@ -343,12 +343,18 @@ void instance_addnpc(struct instance_data *im)
|
||||
int i;
|
||||
|
||||
// First add the NPCs
|
||||
for(i = 0; i < im->cnt_map; i++)
|
||||
map_foreachinallarea(instance_addnpc_sub, im->map[i]->src_m, 0, 0, map[im->map[i]->src_m].xs, map[im->map[i]->src_m].ys, BL_NPC, im->map[i]->m);
|
||||
for (i = 0; i < im->cnt_map; i++) {
|
||||
struct map_data *mapdata = map_getmapdata(im->map[i]->src_m);
|
||||
|
||||
map_foreachinallarea(instance_addnpc_sub, im->map[i]->src_m, 0, 0, mapdata->xs, mapdata->ys, BL_NPC, im->map[i]->m);
|
||||
}
|
||||
|
||||
// Now run their OnInstanceInit
|
||||
for(i = 0; i < im->cnt_map; i++)
|
||||
map_foreachinallarea(instance_npcinit, im->map[i]->m, 0, 0, map[im->map[i]->m].xs, map[im->map[i]->m].ys, BL_NPC, im->map[i]->m);
|
||||
for (i = 0; i < im->cnt_map; i++) {
|
||||
struct map_data *mapdata = map_getmapdata(im->map[i]->m);
|
||||
|
||||
map_foreachinallarea(instance_npcinit, im->map[i]->m, 0, 0, mapdata->xs, mapdata->ys, BL_NPC, im->map[i]->m);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -653,7 +659,9 @@ int instance_destroy(unsigned short instance_id)
|
||||
|
||||
// Run OnInstanceDestroy on all NPCs in the instance
|
||||
for(i = 0; i < im->cnt_map; i++){
|
||||
map_foreachinallarea(instance_npcdestroy, im->map[i]->m, 0, 0, map[im->map[i]->m].xs, map[im->map[i]->m].ys, BL_NPC, im->map[i]->m);
|
||||
struct map_data *mapdata = map_getmapdata(im->map[i]->m);
|
||||
|
||||
map_foreachinallarea(instance_npcdestroy, im->map[i]->m, 0, 0, mapdata->xs, mapdata->ys, BL_NPC, im->map[i]->m);
|
||||
}
|
||||
|
||||
for(i = 0; i < im->cnt_map; i++) {
|
||||
@ -875,7 +883,7 @@ int instance_delusers(unsigned short instance_id)
|
||||
|
||||
// If no one is in the instance, start the idle timer
|
||||
for(i = 0; i < im->cnt_map && im->map[i]->m; i++)
|
||||
users += max(map[im->map[i]->m].users,0);
|
||||
users += max(map_getmapdata(im->map[i]->m)->users,0);
|
||||
|
||||
// We check the actual map.users before being updated, hence the 1
|
||||
// The instance should be empty if users are now <= 1
|
||||
@ -1078,39 +1086,41 @@ void do_reload_instance(void)
|
||||
|
||||
// Reset player to instance beginning
|
||||
iter = mapit_getallusers();
|
||||
for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
|
||||
if(sd && map[sd->bl.m].instance_id) {
|
||||
for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) ) {
|
||||
struct map_data *mapdata = map_getmapdata(sd->bl.m);
|
||||
|
||||
if(sd && mapdata->instance_id) {
|
||||
struct party_data *pd = NULL;
|
||||
struct guild *gd = NULL;
|
||||
struct clan *cd = NULL;
|
||||
unsigned short instance_id;
|
||||
|
||||
im = &instance_data[map[sd->bl.m].instance_id];
|
||||
im = &instance_data[mapdata->instance_id];
|
||||
switch (im->mode) {
|
||||
case IM_NONE:
|
||||
continue;
|
||||
case IM_CHAR:
|
||||
if (sd->instance_id != map[sd->bl.m].instance_id) // Someone who is not instance owner is on instance map
|
||||
if (sd->instance_id != mapdata->instance_id) // Someone who is not instance owner is on instance map
|
||||
continue;
|
||||
instance_id = sd->instance_id;
|
||||
break;
|
||||
case IM_PARTY:
|
||||
if ((!(pd = party_search(sd->status.party_id)) || pd->instance_id != map[sd->bl.m].instance_id)) // Someone not in party is on instance map
|
||||
if ((!(pd = party_search(sd->status.party_id)) || pd->instance_id != mapdata->instance_id)) // Someone not in party is on instance map
|
||||
continue;
|
||||
instance_id = pd->instance_id;
|
||||
break;
|
||||
case IM_GUILD:
|
||||
if (!(gd = guild_search(sd->status.guild_id)) || gd->instance_id != map[sd->bl.m].instance_id) // Someone not in guild is on instance map
|
||||
if (!(gd = guild_search(sd->status.guild_id)) || gd->instance_id != mapdata->instance_id) // Someone not in guild is on instance map
|
||||
continue;
|
||||
instance_id = gd->instance_id;
|
||||
break;
|
||||
case IM_CLAN:
|
||||
if (!(cd = clan_search(sd->status.clan_id)) || cd->instance_id != map[sd->bl.m].instance_id) // Someone not in clan is on instance map
|
||||
if (!(cd = clan_search(sd->status.clan_id)) || cd->instance_id != mapdata->instance_id) // Someone not in clan is on instance map
|
||||
continue;
|
||||
instance_id = cd->instance_id;
|
||||
break;
|
||||
default:
|
||||
ShowError("do_reload_instance: Unexpected instance mode for instance %s (id=%u, mode=%u).\n", (db) ? StringBuf_Value(db->name) : "Unknown", map[sd->bl.m].instance_id, (unsigned short)im->mode);
|
||||
ShowError("do_reload_instance: Unexpected instance mode for instance %s (id=%u, mode=%u).\n", (db) ? StringBuf_Value(db->name) : "Unknown", mapdata->instance_id, (unsigned short)im->mode);
|
||||
continue;
|
||||
}
|
||||
if((db = instance_searchtype_db(im->type)) != NULL && !instance_enter(sd, instance_id, StringBuf_Value(db->name), -1, -1)) { // All good
|
||||
@ -1119,6 +1129,7 @@ void do_reload_instance(void)
|
||||
} else // Something went wrong
|
||||
ShowError("do_reload_instance: Error setting character at instance start: character_id=%d instance=%s.\n",sd->status.char_id,StringBuf_Value(db->name));
|
||||
}
|
||||
}
|
||||
mapit_free(iter);
|
||||
}
|
||||
|
||||
|
@ -690,8 +690,8 @@ int intif_party_changemap(struct map_session_data *sd,int online)
|
||||
if(!sd)
|
||||
return 0;
|
||||
|
||||
if( (m=map_mapindex2mapid(sd->mapindex)) >= 0 && map[m].instance_id )
|
||||
mapindex = map[map[m].instance_src_map].index;
|
||||
if( (m=map_mapindex2mapid(sd->mapindex)) >= 0 && map_getmapdata(m)->instance_id )
|
||||
mapindex = map_getmapdata(map_getmapdata(m)->instance_src_map)->index;
|
||||
else
|
||||
mapindex = sd->mapindex;
|
||||
|
||||
|
@ -1586,7 +1586,7 @@ bool itemdb_isNoEquip(struct item_data *id, uint16 m) {
|
||||
(map_flag_gvg2_no_te(m) && id->flag.no_equip&4) || // GVG
|
||||
(map_getmapflag(m, MF_BATTLEGROUND) && id->flag.no_equip&8) || // Battleground
|
||||
(map_flag_gvg2_te(m) && id->flag.no_equip&16) || // WOE:TE
|
||||
(map_getmapflag(m, MF_RESTRICTED) && id->flag.no_equip&(8*map[m].zone)) // Zone restriction
|
||||
(map_getmapflag(m, MF_RESTRICTED) && id->flag.no_equip&(8*map_getmapdata(m)->zone)) // Zone restriction
|
||||
)
|
||||
return true;
|
||||
return false;
|
||||
|
@ -226,7 +226,7 @@ void log_pick(int id, int16 m, e_log_pick_type type, int amount, struct item* it
|
||||
StringBuf_Printf(&buf, ", `option_parm%d`", i);
|
||||
}
|
||||
StringBuf_Printf(&buf, ") VALUES(NOW(),'%u','%c','%d','%d','%d','%s','%" PRIu64 "','%d'",
|
||||
id, log_picktype2char(type), itm->nameid, amount, itm->refine, map[m].name[0] ? map[m].name : "", itm->unique_id, itm->bound);
|
||||
id, log_picktype2char(type), itm->nameid, amount, itm->refine, map_getmapdata(m)->name[0] ? map_getmapdata(m)->name : "", itm->unique_id, itm->bound);
|
||||
|
||||
for (i = 0; i < MAX_SLOTS; i++)
|
||||
StringBuf_Printf(&buf, ",'%d'", itm->card[i]);
|
||||
@ -250,7 +250,7 @@ void log_pick(int id, int16 m, e_log_pick_type type, int amount, struct item* it
|
||||
return;
|
||||
time(&curtime);
|
||||
strftime(timestring, sizeof(timestring), log_timestamp_format, localtime(&curtime));
|
||||
fprintf(logfp,"%s - %d\t%c\t%hu,%d,%d,%hu,%hu,%hu,%hu,%s,'%" PRIu64 "',%d\n", timestring, id, log_picktype2char(type), itm->nameid, amount, itm->refine, itm->card[0], itm->card[1], itm->card[2], itm->card[3], map[m].name[0]?map[m].name:"", itm->unique_id, itm->bound);
|
||||
fprintf(logfp,"%s - %d\t%c\t%hu,%d,%d,%hu,%hu,%hu,%hu,%s,'%" PRIu64 "',%d\n", timestring, id, log_picktype2char(type), itm->nameid, amount, itm->refine, itm->card[0], itm->card[1], itm->card[2], itm->card[3], map_getmapdata(m)->name[0]?map_getmapdata(m)->name:"", itm->unique_id, itm->bound);
|
||||
fclose(logfp);
|
||||
}
|
||||
}
|
||||
|
774
src/map/map.cpp
774
src/map/map.cpp
File diff suppressed because it is too large
Load Diff
@ -29,6 +29,7 @@ enum E_MAPSERVER_ST {
|
||||
MAPSERVER_ST_LAST
|
||||
};
|
||||
|
||||
struct map_data *map_getmapdata(int16 m);
|
||||
#define msg_config_read(cfgName,isnew) map_msg_config_read(cfgName,isnew)
|
||||
#define msg_txt(sd,msg_number) map_msg_txt(sd,msg_number)
|
||||
#define do_final_msg() map_do_final_msg()
|
||||
@ -773,7 +774,7 @@ int map_getcellp(struct map_data* m,int16 x,int16 y,cell_chk cellchk);
|
||||
void map_setcell(int16 m, int16 x, int16 y, cell_t cell, bool flag);
|
||||
void map_setgatcell(int16 m, int16 x, int16 y, int gat);
|
||||
|
||||
extern std::vector<map_data> map;
|
||||
extern std::map<int16, map_data> map;
|
||||
|
||||
extern int autosave_interval;
|
||||
extern int minsave_interval;
|
||||
|
@ -270,15 +270,17 @@ void mvptomb_destroy(struct mob_data *md) {
|
||||
struct npc_data *nd;
|
||||
|
||||
if ( (nd = map_id2nd(md->tomb_nid)) ) {
|
||||
int16 m = nd->bl.m, i;
|
||||
int16 i;
|
||||
struct map_data *mapdata = map_getmapdata(nd->bl.m);
|
||||
|
||||
clif_clearunit_area(&nd->bl,CLR_OUTSIGHT);
|
||||
map_delblock(&nd->bl);
|
||||
|
||||
ARR_FIND( 0, map[m].npc_num, i, map[m].npc[i] == nd );
|
||||
if( !(i == map[m].npc_num) ) {
|
||||
map[m].npc_num--;
|
||||
map[m].npc[i] = map[m].npc[map[m].npc_num];
|
||||
map[m].npc[map[m].npc_num] = NULL;
|
||||
ARR_FIND( 0, mapdata->npc_num, i, mapdata->npc[i] == nd );
|
||||
if( !(i == mapdata->npc_num) ) {
|
||||
mapdata->npc_num--;
|
||||
mapdata->npc[i] = mapdata->npc[mapdata->npc_num];
|
||||
mapdata->npc[mapdata->npc_num] = NULL;
|
||||
}
|
||||
map_deliddb(&nd->bl);
|
||||
aFree(nd);
|
||||
@ -646,8 +648,9 @@ struct mob_data *mob_once_spawn_sub(struct block_list *bl, int16 m, int16 x, int
|
||||
if (bl && (x < 0 || y < 0))
|
||||
map_search_freecell(bl, m, &x, &y, 1, 1, 0);
|
||||
|
||||
struct map_data *mapdata = map_getmapdata(m);
|
||||
// if none found, pick random position on map
|
||||
if (x <= 0 || x >= map[m].xs || y <= 0 || y >= map[m].ys)
|
||||
if (x <= 0 || x >= mapdata->xs || y <= 0 || y >= mapdata->ys)
|
||||
map_search_freecell(NULL, m, &x, &y, -1, -1, 1);
|
||||
|
||||
data.x = x;
|
||||
@ -682,7 +685,7 @@ int mob_once_spawn(struct map_session_data* sd, int16 m, int16 x, int16 y, const
|
||||
|
||||
if (mob_id == MOBID_EMPERIUM)
|
||||
{
|
||||
struct guild_castle* gc = guild_mapindex2gc(map[m].index);
|
||||
struct guild_castle* gc = guild_mapindex2gc(map_getmapdata(m)->index);
|
||||
struct guild* g = (gc) ? guild_search(gc->guild_id) : nullptr;
|
||||
if (gc)
|
||||
{
|
||||
@ -835,6 +838,9 @@ int mob_spawn_guardian(const char* mapname, int16 x, int16 y, const char* mobnam
|
||||
ShowWarning("mob_spawn_guardian: Map [%s] not found.\n", mapname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct map_data *mapdata = map_getmapdata(m);
|
||||
|
||||
data.m = m;
|
||||
data.num = 1;
|
||||
if(mob_id<=0) {
|
||||
@ -850,13 +856,13 @@ int mob_spawn_guardian(const char* mapname, int16 x, int16 y, const char* mobnam
|
||||
}
|
||||
else if( guardian < 0 || guardian >= MAX_GUARDIANS )
|
||||
{
|
||||
ShowError("mob_spawn_guardian: Invalid guardian index %d for guardian %d (castle map %s)\n", guardian, mob_id, map[m].name);
|
||||
ShowError("mob_spawn_guardian: Invalid guardian index %d for guardian %d (castle map %s)\n", guardian, mob_id, mapdata->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if((x<=0 || y<=0) && !map_search_freecell(NULL, m, &x, &y, -1,-1, 1))
|
||||
{
|
||||
ShowWarning("mob_spawn_guardian: Couldn't locate a spawn cell for guardian class %d (index %d) at castle map %s\n",mob_id, guardian, map[m].name);
|
||||
ShowWarning("mob_spawn_guardian: Couldn't locate a spawn cell for guardian class %d (index %d) at castle map %s\n",mob_id, guardian, mapdata->name);
|
||||
return 0;
|
||||
}
|
||||
data.x = x;
|
||||
@ -866,14 +872,14 @@ int mob_spawn_guardian(const char* mapname, int16 x, int16 y, const char* mobnam
|
||||
if (!mob_parse_dataset(&data))
|
||||
return 0;
|
||||
|
||||
gc=guild_mapname2gc(map[m].name);
|
||||
gc=guild_mapname2gc(mapdata->name);
|
||||
if (gc == NULL)
|
||||
{
|
||||
ShowError("mob_spawn_guardian: No castle set at map %s\n", map[m].name);
|
||||
ShowError("mob_spawn_guardian: No castle set at map %s\n", mapdata->name);
|
||||
return 0;
|
||||
}
|
||||
if (!gc->guild_id)
|
||||
ShowWarning("mob_spawn_guardian: Spawning guardian %d on a castle with no guild (castle map %s)\n", mob_id, map[m].name);
|
||||
ShowWarning("mob_spawn_guardian: Spawning guardian %d on a castle with no guild (castle map %s)\n", mob_id, mapdata->name);
|
||||
else
|
||||
g = guild_search(gc->guild_id);
|
||||
|
||||
@ -883,7 +889,7 @@ int mob_spawn_guardian(const char* mapname, int16 x, int16 y, const char* mobnam
|
||||
if (md2 && md2->bl.type == BL_MOB &&
|
||||
md2->guardian_data && md2->guardian_data->number == guardian)
|
||||
{
|
||||
ShowError("mob_spawn_guardian: Attempted to spawn guardian in position %d which already has a guardian (castle map %s)\n", guardian, map[m].name);
|
||||
ShowError("mob_spawn_guardian: Attempted to spawn guardian in position %d which already has a guardian (castle map %s)\n", guardian, mapdata->name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -947,7 +953,7 @@ int mob_spawn_bg(const char* mapname, int16 x, int16 y, const char* mobname, int
|
||||
data.id = mob_id;
|
||||
if( (x <= 0 || y <= 0) && !map_search_freecell(NULL, m, &x, &y, -1,-1, 1) )
|
||||
{
|
||||
ShowWarning("mob_spawn_bg: Couldn't locate a spawn cell for guardian class %d (bg_id %d) at map %s\n",mob_id, bg_id, map[m].name);
|
||||
ShowWarning("mob_spawn_bg: Couldn't locate a spawn cell for guardian class %d (bg_id %d) at map %s\n",mob_id, bg_id, map_getmapdata(m)->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1186,7 +1192,7 @@ int mob_spawn (struct mob_data *md)
|
||||
|
||||
if(map_addblock(&md->bl))
|
||||
return 2;
|
||||
if( map[md->bl.m].users )
|
||||
if( map_getmapdata(md->bl.m)->users )
|
||||
clif_spawn(&md->bl);
|
||||
skill_unit_move(&md->bl,tick,1);
|
||||
mobskill_use(md, tick, MSC_SPAWN);
|
||||
@ -1404,7 +1410,7 @@ static int mob_warpchase_sub(struct block_list *bl,va_list ap) {
|
||||
if(nd->subtype != NPCTYPE_WARP)
|
||||
return 0; //Not a warp
|
||||
|
||||
if(nd->u.warp.mapindex != map[target->m].index)
|
||||
if(nd->u.warp.mapindex != map_getmapdata(target->m)->index)
|
||||
return 0; //Does not lead to the same map.
|
||||
|
||||
cur_distance = distance_blxy(target, nd->u.warp.x, nd->u.warp.y);
|
||||
@ -1629,7 +1635,7 @@ int mob_randomwalk(struct mob_data *md,unsigned int tick)
|
||||
if(battle_config.mob_stuck_warning) {
|
||||
md->move_fail_count++;
|
||||
if(md->move_fail_count>1000){
|
||||
ShowWarning("MOB can't move. random spawn %d, class = %d, at %s (%d,%d)\n",md->bl.id,md->mob_id,map[md->bl.m].name, md->bl.x, md->bl.y);
|
||||
ShowWarning("MOB can't move. random spawn %d, class = %d, at %s (%d,%d)\n",md->bl.id,md->mob_id,map_getmapdata(md->bl.m)->name, md->bl.x, md->bl.y);
|
||||
md->move_fail_count=0;
|
||||
mob_spawn(md);
|
||||
}
|
||||
@ -2005,7 +2011,7 @@ static int mob_ai_sub_lazy(struct mob_data *md, va_list args)
|
||||
|
||||
tick = va_arg(args,unsigned int);
|
||||
|
||||
if (battle_config.mob_ai&0x20 && map[md->bl.m].users>0)
|
||||
if (battle_config.mob_ai&0x20 && map_getmapdata(md->bl.m)->users>0)
|
||||
return (int)mob_ai_sub_hard(md, tick);
|
||||
|
||||
if (md->bl.prev==NULL || md->status.hp == 0)
|
||||
|
279
src/map/npc.cpp
279
src/map/npc.cpp
@ -350,7 +350,7 @@ static int npc_event_export(struct npc_data *nd, int i)
|
||||
struct event_data *ev;
|
||||
char buf[EVENT_NAME_LENGTH];
|
||||
|
||||
if (nd->bl.m > -1 && map[nd->bl.m].instance_id > 0) { // Block script events in instances
|
||||
if (nd->bl.m > -1 && map_getmapdata(nd->bl.m)->instance_id > 0) { // Block script events in instances
|
||||
int j;
|
||||
|
||||
for (j = 0; j < NPCE_MAX; j++) {
|
||||
@ -981,59 +981,61 @@ int npc_touch_areanpc(struct map_session_data* sd, int16 m, int16 x, int16 y)
|
||||
//if(sd->npc_id)
|
||||
// return 1;
|
||||
|
||||
for(i=0;i<map[m].npc_num;i++)
|
||||
struct map_data *mapdata = map_getmapdata(m);
|
||||
|
||||
for(i=0;i<mapdata->npc_num;i++)
|
||||
{
|
||||
if (map[m].npc[i]->sc.option&OPTION_INVISIBLE) {
|
||||
if (mapdata->npc[i]->sc.option&OPTION_INVISIBLE) {
|
||||
f=0; // a npc was found, but it is disabled; don't print warning
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(map[m].npc[i]->subtype) {
|
||||
switch(mapdata->npc[i]->subtype) {
|
||||
case NPCTYPE_WARP:
|
||||
xs=map[m].npc[i]->u.warp.xs;
|
||||
ys=map[m].npc[i]->u.warp.ys;
|
||||
xs=mapdata->npc[i]->u.warp.xs;
|
||||
ys=mapdata->npc[i]->u.warp.ys;
|
||||
break;
|
||||
case NPCTYPE_SCRIPT:
|
||||
xs=map[m].npc[i]->u.scr.xs;
|
||||
ys=map[m].npc[i]->u.scr.ys;
|
||||
xs=mapdata->npc[i]->u.scr.xs;
|
||||
ys=mapdata->npc[i]->u.scr.ys;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
if( x >= map[m].npc[i]->bl.x-xs && x <= map[m].npc[i]->bl.x+xs
|
||||
&& y >= map[m].npc[i]->bl.y-ys && y <= map[m].npc[i]->bl.y+ys )
|
||||
if( x >= mapdata->npc[i]->bl.x-xs && x <= mapdata->npc[i]->bl.x+xs
|
||||
&& y >= mapdata->npc[i]->bl.y-ys && y <= mapdata->npc[i]->bl.y+ys )
|
||||
break;
|
||||
}
|
||||
if( i == map[m].npc_num )
|
||||
if( i == mapdata->npc_num )
|
||||
{
|
||||
if( f == 1 ) // no npc found
|
||||
ShowError("npc_touch_areanpc : stray NPC cell/NPC not found in the block on coordinates '%s',%d,%d\n", map[m].name, x, y);
|
||||
ShowError("npc_touch_areanpc : stray NPC cell/NPC not found in the block on coordinates '%s',%d,%d\n", mapdata->name, x, y);
|
||||
return 1;
|
||||
}
|
||||
switch(map[m].npc[i]->subtype) {
|
||||
switch(mapdata->npc[i]->subtype) {
|
||||
case NPCTYPE_WARP:
|
||||
if ((!map[m].npc[i]->trigger_on_hidden && (pc_ishiding(sd) || (sd->sc.count && sd->sc.data[SC_CAMOUFLAGE]))) || pc_isdead(sd))
|
||||
if ((!mapdata->npc[i]->trigger_on_hidden && (pc_ishiding(sd) || (sd->sc.count && sd->sc.data[SC_CAMOUFLAGE]))) || pc_isdead(sd))
|
||||
break; // hidden or dead chars cannot use warps
|
||||
if (!pc_job_can_entermap((enum e_job)sd->status.class_, map_mapindex2mapid(map[m].npc[i]->u.warp.mapindex), sd->group_level))
|
||||
if (!pc_job_can_entermap((enum e_job)sd->status.class_, map_mapindex2mapid(mapdata->npc[i]->u.warp.mapindex), sd->group_level))
|
||||
break;
|
||||
if(sd->count_rewarp > 10){
|
||||
ShowWarning("Prevented infinite warp loop for player (%d:%d). Please fix NPC: '%s', path: '%s'\n", sd->status.account_id, sd->status.char_id, map[m].npc[i]->exname, map[m].npc[i]->path);
|
||||
ShowWarning("Prevented infinite warp loop for player (%d:%d). Please fix NPC: '%s', path: '%s'\n", sd->status.account_id, sd->status.char_id, mapdata->npc[i]->exname, mapdata->npc[i]->path);
|
||||
sd->count_rewarp=0;
|
||||
break;
|
||||
}
|
||||
pc_setpos(sd,map[m].npc[i]->u.warp.mapindex,map[m].npc[i]->u.warp.x,map[m].npc[i]->u.warp.y,CLR_OUTSIGHT);
|
||||
pc_setpos(sd,mapdata->npc[i]->u.warp.mapindex,mapdata->npc[i]->u.warp.x,mapdata->npc[i]->u.warp.y,CLR_OUTSIGHT);
|
||||
break;
|
||||
case NPCTYPE_SCRIPT:
|
||||
for (j = i; j < map[m].npc_num; j++) {
|
||||
if (map[m].npc[j]->subtype != NPCTYPE_WARP) {
|
||||
for (j = i; j < mapdata->npc_num; j++) {
|
||||
if (mapdata->npc[j]->subtype != NPCTYPE_WARP) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((sd->bl.x >= (map[m].npc[j]->bl.x - map[m].npc[j]->u.warp.xs) && sd->bl.x <= (map[m].npc[j]->bl.x + map[m].npc[j]->u.warp.xs)) &&
|
||||
(sd->bl.y >= (map[m].npc[j]->bl.y - map[m].npc[j]->u.warp.ys) && sd->bl.y <= (map[m].npc[j]->bl.y + map[m].npc[j]->u.warp.ys))) {
|
||||
if ((!map[m].npc[i]->trigger_on_hidden && (pc_ishiding(sd) || (sd->sc.count && sd->sc.data[SC_CAMOUFLAGE]))) || pc_isdead(sd))
|
||||
if ((sd->bl.x >= (mapdata->npc[j]->bl.x - mapdata->npc[j]->u.warp.xs) && sd->bl.x <= (mapdata->npc[j]->bl.x + mapdata->npc[j]->u.warp.xs)) &&
|
||||
(sd->bl.y >= (mapdata->npc[j]->bl.y - mapdata->npc[j]->u.warp.ys) && sd->bl.y <= (mapdata->npc[j]->bl.y + mapdata->npc[j]->u.warp.ys))) {
|
||||
if ((!mapdata->npc[i]->trigger_on_hidden && (pc_ishiding(sd) || (sd->sc.count && sd->sc.data[SC_CAMOUFLAGE]))) || pc_isdead(sd))
|
||||
break; // hidden or dead chars cannot use warps
|
||||
pc_setpos(sd,map[m].npc[j]->u.warp.mapindex,map[m].npc[j]->u.warp.x,map[m].npc[j]->u.warp.y,CLR_OUTSIGHT);
|
||||
pc_setpos(sd,mapdata->npc[j]->u.warp.mapindex,mapdata->npc[j]->u.warp.x,mapdata->npc[j]->u.warp.y,CLR_OUTSIGHT);
|
||||
found_warp = 1;
|
||||
break;
|
||||
}
|
||||
@ -1043,7 +1045,7 @@ int npc_touch_areanpc(struct map_session_data* sd, int16 m, int16 x, int16 y)
|
||||
break;
|
||||
}
|
||||
|
||||
if( npc_ontouch_event(sd,map[m].npc[i]) > 0 && npc_ontouch2_event(sd,map[m].npc[i]) > 0 )
|
||||
if( npc_ontouch_event(sd,mapdata->npc[i]) > 0 && npc_ontouch2_event(sd,mapdata->npc[i]) > 0 )
|
||||
{ // failed to run OnTouch event, so just click the npc
|
||||
struct unit_data *ud = unit_bl2ud(&sd->bl);
|
||||
if( ud && ud->walkpath.path_pos < ud->walkpath.path_len )
|
||||
@ -1051,8 +1053,8 @@ int npc_touch_areanpc(struct map_session_data* sd, int16 m, int16 x, int16 y)
|
||||
clif_fixpos(&sd->bl);
|
||||
ud->walkpath.path_pos = ud->walkpath.path_len;
|
||||
}
|
||||
sd->areanpc_id = map[m].npc[i]->bl.id;
|
||||
npc_click(sd,map[m].npc[i]);
|
||||
sd->areanpc_id = mapdata->npc[i]->bl.id;
|
||||
npc_click(sd,mapdata->npc[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1063,50 +1065,51 @@ int npc_touch_areanpc(struct map_session_data* sd, int16 m, int16 x, int16 y)
|
||||
// Return 1 if Warped
|
||||
int npc_touch_areanpc2(struct mob_data *md)
|
||||
{
|
||||
int i, m = md->bl.m, x = md->bl.x, y = md->bl.y, id;
|
||||
int i, x = md->bl.x, y = md->bl.y, id;
|
||||
char eventname[EVENT_NAME_LENGTH];
|
||||
struct event_data* ev;
|
||||
int xs, ys;
|
||||
struct map_data *mapdata = map_getmapdata(md->bl.m);
|
||||
|
||||
for( i = 0; i < map[m].npc_num; i++ )
|
||||
for( i = 0; i < mapdata->npc_num; i++ )
|
||||
{
|
||||
if( map[m].npc[i]->sc.option&OPTION_INVISIBLE )
|
||||
if( mapdata->npc[i]->sc.option&OPTION_INVISIBLE )
|
||||
continue;
|
||||
|
||||
switch( map[m].npc[i]->subtype )
|
||||
switch( mapdata->npc[i]->subtype )
|
||||
{
|
||||
case NPCTYPE_WARP:
|
||||
if( !( battle_config.mob_warp&1 ) )
|
||||
continue;
|
||||
xs = map[m].npc[i]->u.warp.xs;
|
||||
ys = map[m].npc[i]->u.warp.ys;
|
||||
xs = mapdata->npc[i]->u.warp.xs;
|
||||
ys = mapdata->npc[i]->u.warp.ys;
|
||||
break;
|
||||
case NPCTYPE_SCRIPT:
|
||||
xs = map[m].npc[i]->u.scr.xs;
|
||||
ys = map[m].npc[i]->u.scr.ys;
|
||||
xs = mapdata->npc[i]->u.scr.xs;
|
||||
ys = mapdata->npc[i]->u.scr.ys;
|
||||
break;
|
||||
default:
|
||||
continue; // Keep Searching
|
||||
}
|
||||
|
||||
if( x >= map[m].npc[i]->bl.x-xs && x <= map[m].npc[i]->bl.x+xs && y >= map[m].npc[i]->bl.y-ys && y <= map[m].npc[i]->bl.y+ys )
|
||||
if( x >= mapdata->npc[i]->bl.x-xs && x <= mapdata->npc[i]->bl.x+xs && y >= mapdata->npc[i]->bl.y-ys && y <= mapdata->npc[i]->bl.y+ys )
|
||||
{ // In the npc touch area
|
||||
switch( map[m].npc[i]->subtype )
|
||||
switch( mapdata->npc[i]->subtype )
|
||||
{
|
||||
case NPCTYPE_WARP:
|
||||
xs = map_mapindex2mapid(map[m].npc[i]->u.warp.mapindex);
|
||||
if( m < 0 )
|
||||
xs = map_mapindex2mapid(mapdata->npc[i]->u.warp.mapindex);
|
||||
if( md->bl.m < 0 )
|
||||
break; // Cannot Warp between map servers
|
||||
if( unit_warp(&md->bl, xs, map[m].npc[i]->u.warp.x, map[m].npc[i]->u.warp.y, CLR_OUTSIGHT) == 0 )
|
||||
if( unit_warp(&md->bl, xs, mapdata->npc[i]->u.warp.x, mapdata->npc[i]->u.warp.y, CLR_OUTSIGHT) == 0 )
|
||||
return 1; // Warped
|
||||
break;
|
||||
case NPCTYPE_SCRIPT:
|
||||
if( map[m].npc[i]->bl.id == md->areanpc_id )
|
||||
if( mapdata->npc[i]->bl.id == md->areanpc_id )
|
||||
break; // Already touch this NPC
|
||||
safesnprintf(eventname, ARRAYLENGTH(eventname), "%s::%s", map[m].npc[i]->exname, script_config.ontouchnpc_event_name);
|
||||
safesnprintf(eventname, ARRAYLENGTH(eventname), "%s::%s", mapdata->npc[i]->exname, script_config.ontouchnpc_event_name);
|
||||
if( (ev = (struct event_data*)strdb_get(ev_db, eventname)) == NULL || ev->nd == NULL )
|
||||
break; // No OnTouchNPC Event
|
||||
md->areanpc_id = map[m].npc[i]->bl.id;
|
||||
md->areanpc_id = mapdata->npc[i]->bl.id;
|
||||
id = md->bl.id; // Stores Unique ID
|
||||
run_script(ev->nd->u.scr.script, ev->pos, md->bl.id, ev->nd->bl.id);
|
||||
if( map_id2md(id) == NULL ) return 1; // Not Warped, but killed
|
||||
@ -1138,10 +1141,13 @@ int npc_check_areanpc(int flag, int16 m, int16 x, int16 y, int16 range)
|
||||
int xs,ys;
|
||||
|
||||
if (range < 0) return 0;
|
||||
|
||||
struct map_data *mapdata = map_getmapdata(m);
|
||||
|
||||
x0 = i16max(x-range, 0);
|
||||
y0 = i16max(y-range, 0);
|
||||
x1 = i16min(x+range, map[m].xs-1);
|
||||
y1 = i16min(y+range, map[m].ys-1);
|
||||
x1 = i16min(x+range, mapdata->xs-1);
|
||||
y1 = i16min(y+range, mapdata->ys-1);
|
||||
|
||||
//First check for npc_cells on the range given
|
||||
i = 0;
|
||||
@ -1154,37 +1160,37 @@ int npc_check_areanpc(int flag, int16 m, int16 x, int16 y, int16 range)
|
||||
if (!i) return 0; //No NPC_CELLs.
|
||||
|
||||
//Now check for the actual NPC on said range.
|
||||
for(i=0;i<map[m].npc_num;i++)
|
||||
for(i=0;i<mapdata->npc_num;i++)
|
||||
{
|
||||
if (map[m].npc[i]->sc.option&OPTION_INVISIBLE)
|
||||
if (mapdata->npc[i]->sc.option&OPTION_INVISIBLE)
|
||||
continue;
|
||||
|
||||
switch(map[m].npc[i]->subtype)
|
||||
switch(mapdata->npc[i]->subtype)
|
||||
{
|
||||
case NPCTYPE_WARP:
|
||||
if (!(flag&1))
|
||||
continue;
|
||||
xs=map[m].npc[i]->u.warp.xs;
|
||||
ys=map[m].npc[i]->u.warp.ys;
|
||||
xs=mapdata->npc[i]->u.warp.xs;
|
||||
ys=mapdata->npc[i]->u.warp.ys;
|
||||
break;
|
||||
case NPCTYPE_SCRIPT:
|
||||
if (!(flag&2))
|
||||
continue;
|
||||
xs=map[m].npc[i]->u.scr.xs;
|
||||
ys=map[m].npc[i]->u.scr.ys;
|
||||
xs=mapdata->npc[i]->u.scr.xs;
|
||||
ys=mapdata->npc[i]->u.scr.ys;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
if( x1 >= map[m].npc[i]->bl.x-xs && x0 <= map[m].npc[i]->bl.x+xs
|
||||
&& y1 >= map[m].npc[i]->bl.y-ys && y0 <= map[m].npc[i]->bl.y+ys )
|
||||
if( x1 >= mapdata->npc[i]->bl.x-xs && x0 <= mapdata->npc[i]->bl.x+xs
|
||||
&& y1 >= mapdata->npc[i]->bl.y-ys && y0 <= mapdata->npc[i]->bl.y+ys )
|
||||
break; // found a npc
|
||||
}
|
||||
if (i==map[m].npc_num)
|
||||
if (i==mapdata->npc_num)
|
||||
return 0;
|
||||
|
||||
return (map[m].npc[i]->bl.id);
|
||||
return (mapdata->npc[i]->bl.id);
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
@ -1418,9 +1424,10 @@ static enum e_CASHSHOP_ACK npc_cashshop_process_payment(struct npc_data *nd, int
|
||||
case NPCTYPE_ITEMSHOP:
|
||||
{
|
||||
struct item_data *id = itemdb_exists(nd->u.shop.itemshop_nameid);
|
||||
struct map_data *mapdata = map_getmapdata(nd->bl.m);
|
||||
|
||||
if (!id) { // Item Data is checked at script parsing but in case of item_db reload, check again.
|
||||
ShowWarning("Failed to find sellitem %hu for itemshop NPC '%s' (%s, %d, %d)!\n", nd->u.shop.itemshop_nameid, nd->exname, map[nd->bl.m].name, nd->bl.x, nd->bl.y);
|
||||
ShowWarning("Failed to find sellitem %hu for itemshop NPC '%s' (%s, %d, %d)!\n", nd->u.shop.itemshop_nameid, nd->exname, mapdata->name, nd->bl.x, nd->bl.y);
|
||||
return ERROR_TYPE_PURCHASE_FAIL;
|
||||
}
|
||||
if (cost[0] < (price - points)) {
|
||||
@ -1433,7 +1440,7 @@ static enum e_CASHSHOP_ACK npc_cashshop_process_payment(struct npc_data *nd, int
|
||||
return ERROR_TYPE_PURCHASE_FAIL;
|
||||
}
|
||||
if (pc_delitem(sd, pc_search_inventory(sd, nd->u.shop.itemshop_nameid), price - points, 0, 0, LOG_TYPE_NPC)) {
|
||||
ShowWarning("Failed to delete item %hu from '%s' at itemshop NPC '%s' (%s, %d, %d)!\n", nd->u.shop.itemshop_nameid, sd->status.name, nd->exname, map[nd->bl.m].name, nd->bl.x, nd->bl.y);
|
||||
ShowWarning("Failed to delete item %hu from '%s' at itemshop NPC '%s' (%s, %d, %d)!\n", nd->u.shop.itemshop_nameid, sd->status.name, nd->exname, mapdata->name, nd->bl.x, nd->bl.y);
|
||||
return ERROR_TYPE_PURCHASE_FAIL;
|
||||
}
|
||||
}
|
||||
@ -1673,7 +1680,7 @@ int npc_cashshop_buy(struct map_session_data *sd, unsigned short nameid, int amo
|
||||
{
|
||||
ShowWarning("npc_cashshop_buy: Item '%s' (%hu) price overflow attempt!\n", item->name, nameid);
|
||||
ShowDebug("(NPC:'%s' (%s,%d,%d), player:'%s' (%d/%d), value:%d, amount:%d)\n",
|
||||
nd->exname, map[nd->bl.m].name, nd->bl.x, nd->bl.y, sd->status.name, sd->status.account_id, sd->status.char_id, nd->u.shop.shop_item[i].value, amount);
|
||||
nd->exname, map_getmapdata(nd->bl.m)->name, nd->bl.x, nd->bl.y, sd->status.name, sd->status.account_id, sd->status.char_id, nd->u.shop.shop_item[i].value, amount);
|
||||
return ERROR_TYPE_ITEM_ID;
|
||||
}
|
||||
|
||||
@ -2064,24 +2071,26 @@ uint8 npc_selllist(struct map_session_data* sd, int n, unsigned short *item_list
|
||||
//This doesn't remove it from map_db
|
||||
int npc_remove_map(struct npc_data* nd)
|
||||
{
|
||||
int16 m,i;
|
||||
int16 i;
|
||||
nullpo_retr(1, nd);
|
||||
|
||||
if(nd->bl.prev == NULL || nd->bl.m < 0)
|
||||
return 1; //Not assigned to a map.
|
||||
m = nd->bl.m;
|
||||
|
||||
struct map_data *mapdata = map_getmapdata(nd->bl.m);
|
||||
|
||||
if (nd->subtype == NPCTYPE_SCRIPT)
|
||||
skill_clear_unitgroup(&nd->bl);
|
||||
clif_clearunit_area(&nd->bl,CLR_RESPAWN);
|
||||
npc_unsetcells(nd);
|
||||
map_delblock(&nd->bl);
|
||||
//Remove npc from map[].npc list. [Skotlex]
|
||||
ARR_FIND( 0, map[m].npc_num, i, map[m].npc[i] == nd );
|
||||
if( i == map[m].npc_num ) return 2; //failed to find it?
|
||||
ARR_FIND( 0, mapdata->npc_num, i, mapdata->npc[i] == nd );
|
||||
if( i == mapdata->npc_num ) return 2; //failed to find it?
|
||||
|
||||
map[m].npc_num--;
|
||||
map[m].npc[i] = map[m].npc[map[m].npc_num];
|
||||
map[m].npc[map[m].npc_num] = NULL;
|
||||
mapdata->npc_num--;
|
||||
mapdata->npc[i] = mapdata->npc[mapdata->npc_num];
|
||||
mapdata->npc[mapdata->npc_num] = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2361,8 +2370,8 @@ static void npc_parsename(struct npc_data* nd, const char* name, const char* sta
|
||||
snprintf(newname, ARRAYLENGTH(newname), "%d_%d_%d_%d", i, nd->bl.m, nd->bl.x, nd->bl.y);
|
||||
} while( npc_name2id(newname) != NULL );
|
||||
|
||||
strcpy(this_mapname, (nd->bl.m==-1?"(not on a map)":mapindex_id2name(map[nd->bl.m].index)));
|
||||
strcpy(other_mapname, (dnd->bl.m==-1?"(not on a map)":mapindex_id2name(map[dnd->bl.m].index)));
|
||||
strcpy(this_mapname, (nd->bl.m==-1?"(not on a map)":mapindex_id2name(map_getmapdata(nd->bl.m)->index)));
|
||||
strcpy(other_mapname, (dnd->bl.m==-1?"(not on a map)":mapindex_id2name(map_getmapdata(dnd->bl.m)->index)));
|
||||
|
||||
ShowWarning("npc_parsename: Duplicate unique name in file '%s', line'%d'. Renaming '%s' to '%s'.\n", filepath, strline(buffer,start-buffer), nd->exname, newname);
|
||||
ShowDebug("this npc:\n display name '%s'\n unique name '%s'\n map=%s, x=%d, y=%d\n", nd->name, nd->exname, this_mapname, nd->bl.x, nd->bl.y);
|
||||
@ -2519,7 +2528,7 @@ struct npc_data* npc_add_warp(char* name, short from_mapid, short from_x, short
|
||||
status_set_viewdata(&nd->bl, nd->class_);
|
||||
status_change_init(&nd->bl);
|
||||
unit_dataset(&nd->bl);
|
||||
if( map[nd->bl.m].users )
|
||||
if( map_getmapdata(nd->bl.m)->users )
|
||||
clif_spawn(&nd->bl);
|
||||
strdb_put(npcname_db, nd->exname, nd);
|
||||
|
||||
@ -2563,8 +2572,10 @@ static const char* npc_parse_warp(char* w1, char* w2, char* w3, char* w4, const
|
||||
return strchr(start,'\n');// skip and continue
|
||||
}
|
||||
|
||||
if( m != -1 && ( x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys ) ) {
|
||||
ShowWarning("npc_parse_warp: coordinates %d/%d are out of bounds in map %s(%dx%d), in file '%s', line '%d'\n", x, y, map[m].name, map[m].xs, map[m].ys,filepath,strline(buffer,start-buffer));
|
||||
struct map_data *mapdata = map_getmapdata(m);
|
||||
|
||||
if( m != -1 && ( x < 0 || x >= mapdata->xs || y < 0 || y >= mapdata->ys ) ) {
|
||||
ShowWarning("npc_parse_warp: coordinates %d/%d are out of bounds in map %s(%dx%d), in file '%s', line '%d'\n", x, y, mapdata->name, mapdata->xs, mapdata->ys,filepath,strline(buffer,start-buffer));
|
||||
}
|
||||
|
||||
nd = npc_create_npc(m, x, y);
|
||||
@ -2595,7 +2606,7 @@ static const char* npc_parse_warp(char* w1, char* w2, char* w3, char* w4, const
|
||||
status_set_viewdata(&nd->bl, nd->class_);
|
||||
status_change_init(&nd->bl);
|
||||
unit_dataset(&nd->bl);
|
||||
if( map[nd->bl.m].users )
|
||||
if( map_getmapdata(nd->bl.m)->users )
|
||||
clif_spawn(&nd->bl);
|
||||
strdb_put(npcname_db, nd->exname, nd);
|
||||
|
||||
@ -2647,8 +2658,10 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
|
||||
m = map_mapname2mapid(mapname);
|
||||
}
|
||||
|
||||
if( m != -1 && ( x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys ) ) {
|
||||
ShowWarning("npc_parse_shop: coordinates %d/%d are out of bounds in map %s(%dx%d), in file '%s', line '%d'\n", x, y, map[m].name, map[m].xs, map[m].ys,filepath,strline(buffer,start-buffer));
|
||||
struct map_data *mapdata = map_getmapdata(m);
|
||||
|
||||
if( m != -1 && ( x < 0 || x >= mapdata->xs || y < 0 || y >= mapdata->ys ) ) {
|
||||
ShowWarning("npc_parse_shop: coordinates %d/%d are out of bounds in map %s(%dx%d), in file '%s', line '%d'\n", x, y, mapdata->name, mapdata->xs, mapdata->ys,filepath,strline(buffer,start-buffer));
|
||||
}
|
||||
|
||||
if( !strcasecmp(w2,"cashshop") )
|
||||
@ -2830,7 +2843,7 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
|
||||
nd->ud.dir = (uint8)dir;
|
||||
if( nd->class_ != JT_FAKENPC ){
|
||||
status_set_viewdata(&nd->bl, nd->class_);
|
||||
if( map[nd->bl.m].users )
|
||||
if( map_getmapdata(nd->bl.m)->users )
|
||||
clif_spawn(&nd->bl);
|
||||
}
|
||||
} else
|
||||
@ -3065,7 +3078,7 @@ static const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, cons
|
||||
if( nd->class_ != JT_FAKENPC )
|
||||
{
|
||||
status_set_viewdata(&nd->bl, nd->class_);
|
||||
if( map[nd->bl.m].users )
|
||||
if( map_getmapdata(nd->bl.m)->users )
|
||||
clif_spawn(&nd->bl);
|
||||
}
|
||||
}
|
||||
@ -3158,8 +3171,10 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
|
||||
m = map_mapname2mapid(mapname);
|
||||
}
|
||||
|
||||
if( m != -1 && ( x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys ) ) {
|
||||
ShowError("npc_parse_duplicate: coordinates %d/%d are out of bounds in map %s(%dx%d), in file '%s', line '%d'\n", x, y, map[m].name, map[m].xs, map[m].ys,filepath,strline(buffer,start-buffer));
|
||||
struct map_data *mapdata = map_getmapdata(m);
|
||||
|
||||
if( m != -1 && ( x < 0 || x >= mapdata->xs || y < 0 || y >= mapdata->ys ) ) {
|
||||
ShowError("npc_parse_duplicate: coordinates %d/%d are out of bounds in map %s(%dx%d), in file '%s', line '%d'\n", x, y, mapdata->name, mapdata->xs, mapdata->ys,filepath,strline(buffer,start-buffer));
|
||||
}
|
||||
|
||||
if( type == NPCTYPE_WARP && sscanf(w4, "%6hd,%6hd", &xs, &ys) == 2 );// <spanx>,<spany>
|
||||
@ -3222,7 +3237,7 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
|
||||
return end;
|
||||
if( nd->class_ != JT_FAKENPC ) {
|
||||
status_set_viewdata(&nd->bl, nd->class_);
|
||||
if( map[nd->bl.m].users )
|
||||
if( map_getmapdata(nd->bl.m)->users )
|
||||
clif_spawn(&nd->bl);
|
||||
}
|
||||
} else {
|
||||
@ -3245,7 +3260,7 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
|
||||
}
|
||||
|
||||
if(!strcmp(filepath,"INSTANCING")) //Instance NPCs will use this for commands
|
||||
nd->instance_id = map[m].instance_id;
|
||||
nd->instance_id = mapdata->instance_id;
|
||||
|
||||
nd->u.scr.timerid = INVALID_TIMER;
|
||||
|
||||
@ -3254,33 +3269,34 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
|
||||
|
||||
int npc_duplicate4instance(struct npc_data *snd, int16 m) {
|
||||
char newname[NPC_NAME_LENGTH+1];
|
||||
struct map_data *mapdata = map_getmapdata(m);
|
||||
|
||||
if( map[m].instance_id == 0 )
|
||||
if( mapdata->instance_id == 0 )
|
||||
return 1;
|
||||
|
||||
snprintf(newname, ARRAYLENGTH(newname), "dup_%d_%d", map[m].instance_id, snd->bl.id);
|
||||
snprintf(newname, ARRAYLENGTH(newname), "dup_%d_%d", mapdata->instance_id, snd->bl.id);
|
||||
if( npc_name2id(newname) != NULL ) { // Name already in use
|
||||
ShowError("npc_duplicate4instance: the npcname (%s) is already in use while trying to duplicate npc %s in instance %d.\n", newname, snd->exname, map[m].instance_id);
|
||||
ShowError("npc_duplicate4instance: the npcname (%s) is already in use while trying to duplicate npc %s in instance %d.\n", newname, snd->exname, mapdata->instance_id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( snd->subtype == NPCTYPE_WARP ) { // Adjust destination, if instanced
|
||||
struct npc_data *wnd = NULL; // New NPC
|
||||
struct instance_data *im = &instance_data[map[m].instance_id];
|
||||
struct instance_data *im = &instance_data[mapdata->instance_id];
|
||||
int dm = map_mapindex2mapid(snd->u.warp.mapindex), imap = 0, i;
|
||||
if( dm < 0 ) return 1;
|
||||
|
||||
for(i = 0; i < im->cnt_map; i++)
|
||||
if(im->map[i]->m && map_mapname2mapid(map[im->map[i]->src_m].name) == dm) {
|
||||
imap = map_mapname2mapid(map[im->map[i]->m].name);
|
||||
if(im->map[i]->m && map_mapname2mapid(map_getmapdata(im->map[i]->src_m)->name) == dm) {
|
||||
imap = map_mapname2mapid(map_getmapdata(im->map[i]->m)->name);
|
||||
break; // Instance map matches destination, update to instance map
|
||||
}
|
||||
|
||||
if(!imap)
|
||||
imap = map_mapname2mapid(map[dm].name);
|
||||
imap = map_mapname2mapid(map_getmapdata(dm)->name);
|
||||
|
||||
if( imap == -1 ) {
|
||||
ShowError("npc_duplicate4instance: warp (%s) leading to instanced map (%s), but instance map is not attached to current instance.\n", map[dm].name, snd->exname);
|
||||
ShowError("npc_duplicate4instance: warp (%s) leading to instanced map (%s), but instance map is not attached to current instance.\n", map_getmapdata(dm)->name, snd->exname);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -3305,14 +3321,14 @@ int npc_duplicate4instance(struct npc_data *snd, int16 m) {
|
||||
status_set_viewdata(&wnd->bl, wnd->class_);
|
||||
status_change_init(&wnd->bl);
|
||||
unit_dataset(&wnd->bl);
|
||||
if( map[wnd->bl.m].users )
|
||||
if( map_getmapdata(wnd->bl.m)->users )
|
||||
clif_spawn(&wnd->bl);
|
||||
strdb_put(npcname_db, wnd->exname, wnd);
|
||||
} else {
|
||||
static char w1[50], w2[50], w3[50], w4[50];
|
||||
const char* stat_buf = "- call from instancing subsystem -\n";
|
||||
|
||||
snprintf(w1, sizeof(w1), "%s,%d,%d,%d", map[m].name, snd->bl.x, snd->bl.y, snd->ud.dir);
|
||||
snprintf(w1, sizeof(w1), "%s,%d,%d,%d", mapdata->name, snd->bl.x, snd->bl.y, snd->ud.dir);
|
||||
snprintf(w2, sizeof(w2), "duplicate(%s)", snd->exname);
|
||||
snprintf(w3, sizeof(w3), "%s::%s", snd->name, newname);
|
||||
|
||||
@ -3580,12 +3596,14 @@ void npc_unsetcells(struct npc_data* nd)
|
||||
if (m < 0 || xs < 0 || ys < 0)
|
||||
return;
|
||||
|
||||
struct map_data *mapdata = map_getmapdata(m);
|
||||
|
||||
//Locate max range on which we can locate npc cells
|
||||
//FIXME: does this really do what it's supposed to do? [ultramage]
|
||||
for(x0 = x-xs; x0 > 0 && map_getcell(m, x0, y, CELL_CHKNPC); x0--);
|
||||
for(x1 = x+xs; x1 < map[m].xs-1 && map_getcell(m, x1, y, CELL_CHKNPC); x1++);
|
||||
for(x1 = x+xs; x1 < mapdata->xs-1 && map_getcell(m, x1, y, CELL_CHKNPC); x1++);
|
||||
for(y0 = y-ys; y0 > 0 && map_getcell(m, x, y0, CELL_CHKNPC); y0--);
|
||||
for(y1 = y+ys; y1 < map[m].ys-1 && map_getcell(m, x, y1, CELL_CHKNPC); y1++);
|
||||
for(y1 = y+ys; y1 < mapdata->ys-1 && map_getcell(m, x, y1, CELL_CHKNPC); y1++);
|
||||
|
||||
//Erase this npc's cells
|
||||
for (i = y-ys; i <= y+ys; i++)
|
||||
@ -3598,12 +3616,13 @@ void npc_unsetcells(struct npc_data* nd)
|
||||
|
||||
bool npc_movenpc(struct npc_data* nd, int16 x, int16 y)
|
||||
{
|
||||
const int16 m = nd->bl.m;
|
||||
if (m < 0 || nd->bl.prev == NULL)
|
||||
if (nd->bl.m < 0 || nd->bl.prev == NULL)
|
||||
return false; //Not on a map.
|
||||
|
||||
x = cap_value(x, 0, map[m].xs-1);
|
||||
y = cap_value(y, 0, map[m].ys-1);
|
||||
struct map_data *mapdata = map_getmapdata(nd->bl.m);
|
||||
|
||||
x = cap_value(x, 0, mapdata->xs-1);
|
||||
y = cap_value(y, 0, mapdata->ys-1);
|
||||
|
||||
map_foreachinallrange(clif_outsight, &nd->bl, AREA_SIZE, BL_PC, &nd->bl);
|
||||
map_moveblock(&nd->bl, x, y, gettick());
|
||||
@ -3620,7 +3639,7 @@ void npc_setdisplayname(struct npc_data* nd, const char* newname)
|
||||
nullpo_retv(nd);
|
||||
|
||||
safestrncpy(nd->name, newname, sizeof(nd->name));
|
||||
if( map[nd->bl.m].users )
|
||||
if( map_getmapdata(nd->bl.m)->users )
|
||||
clif_name_area(&nd->bl);
|
||||
}
|
||||
|
||||
@ -3635,11 +3654,13 @@ void npc_setclass(struct npc_data* nd, short class_)
|
||||
if( nd->class_ == class_ )
|
||||
return;
|
||||
|
||||
if( map[nd->bl.m].users )
|
||||
struct map_data *mapdata = map_getmapdata(nd->bl.m);
|
||||
|
||||
if( mapdata->users )
|
||||
clif_clearunit_area(&nd->bl, CLR_OUTSIGHT);// fade out
|
||||
nd->class_ = class_;
|
||||
status_set_viewdata(&nd->bl, class_);
|
||||
if( map[nd->bl.m].users )
|
||||
if( mapdata->users )
|
||||
clif_spawn(&nd->bl);// fade in
|
||||
}
|
||||
|
||||
@ -3797,9 +3818,11 @@ static const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const c
|
||||
return strchr(start,'\n');// skip and continue
|
||||
mob.m = (unsigned short)m;
|
||||
|
||||
if( x < 0 || x >= map[mob.m].xs || y < 0 || y >= map[mob.m].ys )
|
||||
struct map_data *mapdata = map_getmapdata(m);
|
||||
|
||||
if( x < 0 || x >= mapdata->xs || y < 0 || y >= mapdata->ys )
|
||||
{
|
||||
ShowError("npc_parse_mob: Spawn coordinates out of range: %s (%d,%d), map size is (%d,%d) - %s %s (file '%s', line '%d').\n", map[mob.m].name, x, y, (map[mob.m].xs-1), (map[mob.m].ys-1), w1, w3, filepath, strline(buffer,start-buffer));
|
||||
ShowError("npc_parse_mob: Spawn coordinates out of range: %s (%d,%d), map size is (%d,%d) - %s %s (file '%s', line '%d').\n", mapdata->name, x, y, (mapdata->xs-1), (mapdata->ys-1), w1, w3, filepath, strline(buffer,start-buffer));
|
||||
return strchr(start,'\n');// skip and continue
|
||||
}
|
||||
|
||||
@ -3894,7 +3917,7 @@ static const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const c
|
||||
}
|
||||
|
||||
//Update mob spawn lookup database
|
||||
struct spawn_info spawn = { map[mob.m].index, mob.num };
|
||||
struct spawn_info spawn = { mapdata->index, mob.num };
|
||||
mob_add_spawn(mob_id, spawn);
|
||||
|
||||
//Now that all has been validated. We allocate the actual memory that the re-spawn data will use.
|
||||
@ -3910,7 +3933,7 @@ static const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const c
|
||||
// check if target map has players
|
||||
// (usually shouldn't occur when map server is just starting,
|
||||
// but not the case when we do @reloadscript
|
||||
if( map[data->m].users > 0 )
|
||||
if( map_getmapdata(data->m)->users > 0 )
|
||||
npc_parse_mob2(data);
|
||||
}
|
||||
else
|
||||
@ -4035,7 +4058,7 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con
|
||||
if (sscanf(w4, "%11d", &args.flag_val) == 1)
|
||||
map_setmapflag_sub(m, MF_RESTRICTED, true, &args);
|
||||
else // Could not be read, no value defined; don't remove as other restrictions may be set on the map
|
||||
ShowWarning("npc_parse_mapflag: Zone value not set for the restricted mapflag! Skipped flag from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer));
|
||||
ShowWarning("npc_parse_mapflag: Zone value not set for the restricted mapflag! Skipped flag from %s (file '%s', line '%d').\n", map_getmapdata(m)->name, filepath, strline(buffer,start-buffer));
|
||||
} else
|
||||
map_setmapflag(m, MF_RESTRICTED, false);
|
||||
break;
|
||||
@ -4088,7 +4111,7 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con
|
||||
else { // Adjusted damage for specified skill
|
||||
args.flag_val = 1;
|
||||
map_setmapflag_sub(m, MF_SKILL_DAMAGE, true, &args);
|
||||
map_skill_damage_add(&map[m], skill_name2id(skill_name), args.skill_damage.rate, args.skill_damage.caster);
|
||||
map_skill_damage_add(map_getmapdata(m), skill_name2id(skill_name), args.skill_damage.rate, args.skill_damage.caster);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4254,7 +4277,10 @@ int npc_parsesrcfile(const char* filepath, bool runOnInit)
|
||||
p = strchr(p,'\n');// next line
|
||||
continue;
|
||||
}
|
||||
if (x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys) {
|
||||
|
||||
struct map_data *mapdata = map_getmapdata(m);
|
||||
|
||||
if (x < 0 || x >= mapdata->xs || y < 0 || y >= mapdata->ys) {
|
||||
ShowError("npc_parsesrcfile: Unknown coordinates ('%d', '%d') for map '%s' in file '%s', line '%d'. Skipping line...\n", x, y, mapname, filepath, strline(buffer,p-buffer));
|
||||
if( strcasecmp(w2,"script") == 0 && count > 3 )
|
||||
{
|
||||
@ -4430,20 +4456,22 @@ int npc_reload(void) {
|
||||
|
||||
// dynamic check by [random]
|
||||
if( battle_config.dynamic_mobs ){
|
||||
for( int16 m = 0; m < map.size(); m++ ){
|
||||
for( auto& pair : map ){
|
||||
for( int16 i = 0; i < MAX_MOB_LIST_PER_MAP; i++ ){
|
||||
if (map[m].moblist[i] != NULL) {
|
||||
aFree(map[m].moblist[i]);
|
||||
map[m].moblist[i] = NULL;
|
||||
struct map_data *mapdata = &pair.second;
|
||||
|
||||
if (mapdata->moblist[i] != NULL) {
|
||||
aFree(mapdata->moblist[i]);
|
||||
mapdata->moblist[i] = NULL;
|
||||
}
|
||||
if( map[m].mob_delete_timer != INVALID_TIMER )
|
||||
if( mapdata->mob_delete_timer != INVALID_TIMER )
|
||||
{ // Mobs were removed anyway,so delete the timer [Inkfish]
|
||||
delete_timer(map[m].mob_delete_timer, map_removemobs_timer);
|
||||
map[m].mob_delete_timer = INVALID_TIMER;
|
||||
delete_timer(mapdata->mob_delete_timer, map_removemobs_timer);
|
||||
mapdata->mob_delete_timer = INVALID_TIMER;
|
||||
}
|
||||
|
||||
if( map[m].npc_num > 0 ){
|
||||
ShowWarning( "npc_reload: %d npcs weren't removed at map %s!\n", map[m].npc_num, map[m].name );
|
||||
if( mapdata->npc_num > 0 ){
|
||||
ShowWarning( "npc_reload: %d npcs weren't removed at map %s!\n", mapdata->npc_num, mapdata->name );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4553,28 +4581,31 @@ static void npc_debug_warps_sub(struct npc_data* nd)
|
||||
if (m < 0) return; //Warps to another map, nothing to do about it.
|
||||
if (nd->u.warp.x == 0 && nd->u.warp.y == 0) return; // random warp
|
||||
|
||||
struct map_data *mapdata = map_getmapdata(m);
|
||||
struct map_data *mapdata_nd = map_getmapdata(nd->bl.m);
|
||||
|
||||
if (map_getcell(m, nd->u.warp.x, nd->u.warp.y, CELL_CHKNPC)) {
|
||||
ShowWarning("Warp %s at %s(%d,%d) warps directly on top of an area npc at %s(%d,%d)\n",
|
||||
nd->name,
|
||||
map[nd->bl.m].name, nd->bl.x, nd->bl.y,
|
||||
map[m].name, nd->u.warp.x, nd->u.warp.y
|
||||
mapdata_nd->name, nd->bl.x, nd->bl.y,
|
||||
mapdata->name, nd->u.warp.x, nd->u.warp.y
|
||||
);
|
||||
}
|
||||
if (map_getcell(m, nd->u.warp.x, nd->u.warp.y, CELL_CHKNOPASS)) {
|
||||
ShowWarning("Warp %s at %s(%d,%d) warps to a non-walkable tile at %s(%d,%d)\n",
|
||||
nd->name,
|
||||
map[nd->bl.m].name, nd->bl.x, nd->bl.y,
|
||||
map[m].name, nd->u.warp.x, nd->u.warp.y
|
||||
mapdata_nd->name, nd->bl.x, nd->bl.y,
|
||||
mapdata->name, nd->u.warp.x, nd->u.warp.y
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static void npc_debug_warps(void)
|
||||
{
|
||||
int16 m, i;
|
||||
for (m = 0; m < map.size(); m++)
|
||||
for (i = 0; i < map[m].npc_num; i++)
|
||||
npc_debug_warps_sub(map[m].npc[i]);
|
||||
static void npc_debug_warps(void){
|
||||
for( auto& pair : map ){
|
||||
for( int i = 0; i < pair.second.npc_num; i++ ){
|
||||
npc_debug_warps_sub( pair.second.npc[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
|
@ -675,11 +675,11 @@ int party_member_withdraw(int party_id, uint32 account_id, uint32 char_id, char
|
||||
//TODO: hp bars should be cleared too
|
||||
|
||||
if( p->instance_id ) {
|
||||
int16 m = sd->bl.m;
|
||||
struct map_data *mapdata = map_getmapdata(sd->bl.m);
|
||||
|
||||
if( map[m].instance_id ) { // User was on the instance map
|
||||
if( map[m].save.map )
|
||||
pc_setpos(sd, map[m].save.map, map[m].save.x, map[m].save.y, CLR_TELEPORT);
|
||||
if( mapdata->instance_id ) { // User was on the instance map
|
||||
if( mapdata->save.map )
|
||||
pc_setpos(sd, mapdata->save.map, mapdata->save.x, mapdata->save.y, CLR_TELEPORT);
|
||||
else
|
||||
pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT);
|
||||
}
|
||||
|
@ -79,11 +79,10 @@ void do_final_path(){
|
||||
*------------------------------------------*/
|
||||
int path_blownpos(int16 m,int16 x0,int16 y0,int16 dx,int16 dy,int count)
|
||||
{
|
||||
struct map_data *md;
|
||||
struct map_data *mapdata = map_getmapdata(m);
|
||||
|
||||
if( !map[m].cell )
|
||||
if( !mapdata->cell )
|
||||
return -1;
|
||||
md = &map[m];
|
||||
|
||||
if( count>25 ){ //Cap to prevent too much processing...?
|
||||
ShowWarning("path_blownpos: count too many %d !\n",count);
|
||||
@ -97,14 +96,14 @@ int path_blownpos(int16 m,int16 x0,int16 y0,int16 dx,int16 dy,int count)
|
||||
|
||||
while( count > 0 && (dx != 0 || dy != 0) )
|
||||
{
|
||||
if( !map_getcellp(md,x0+dx,y0+dy,CELL_CHKPASS) )
|
||||
if( !map_getcellp(mapdata,x0+dx,y0+dy,CELL_CHKPASS) )
|
||||
{
|
||||
if (battle_config.path_blown_halt)
|
||||
break;
|
||||
else
|
||||
{// attempt partial movement
|
||||
int fx = ( dx != 0 && map_getcellp(md,x0+dx,y0,CELL_CHKPASS) );
|
||||
int fy = ( dy != 0 && map_getcellp(md,x0,y0+dy,CELL_CHKPASS) );
|
||||
int fx = ( dx != 0 && map_getcellp(mapdata,x0+dx,y0,CELL_CHKPASS) );
|
||||
int fy = ( dy != 0 && map_getcellp(mapdata,x0,y0+dy,CELL_CHKPASS) );
|
||||
if( fx && fy )
|
||||
{
|
||||
if(rnd()&1)
|
||||
@ -135,15 +134,14 @@ bool path_search_long(struct shootpath_data *spd,int16 m,int16 x0,int16 y0,int16
|
||||
int dx, dy;
|
||||
int wx = 0, wy = 0;
|
||||
int weight;
|
||||
struct map_data *md;
|
||||
struct map_data *mapdata = map_getmapdata(m);
|
||||
struct shootpath_data s_spd;
|
||||
|
||||
if( spd == NULL )
|
||||
spd = &s_spd; // use dummy output variable
|
||||
|
||||
if (!map[m].cell)
|
||||
if (!mapdata->cell)
|
||||
return false;
|
||||
md = &map[m];
|
||||
|
||||
dx = (x1 - x0);
|
||||
if (dx < 0) {
|
||||
@ -187,7 +185,7 @@ bool path_search_long(struct shootpath_data *spd,int16 m,int16 x0,int16 y0,int16
|
||||
spd->y[spd->len] = y0;
|
||||
spd->len++;
|
||||
}
|
||||
if ((x0 != x1 || y0 != y1) && map_getcellp(md,x0,y0,cell))
|
||||
if ((x0 != x1 || y0 != y1) && map_getcellp(mapdata,x0,y0,cell))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -273,7 +271,7 @@ static int add_path(struct node_heap *heap, struct path_node *tp, int16 x, int16
|
||||
bool path_search(struct walkpath_data *wpd, int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int flag, cell_chk cell)
|
||||
{
|
||||
register int i, x, y, dx = 0, dy = 0;
|
||||
struct map_data *md;
|
||||
struct map_data *mapdata = map_getmapdata(m);
|
||||
struct walkpath_data s_wpd;
|
||||
|
||||
if (flag&2)
|
||||
@ -282,17 +280,15 @@ bool path_search(struct walkpath_data *wpd, int16 m, int16 x0, int16 y0, int16 x
|
||||
if (wpd == NULL)
|
||||
wpd = &s_wpd; // use dummy output variable
|
||||
|
||||
if (!map[m].cell)
|
||||
if (!mapdata->cell)
|
||||
return false;
|
||||
|
||||
md = &map[m];
|
||||
|
||||
//Do not check starting cell as that would get you stuck.
|
||||
if (x0 < 0 || x0 >= md->xs || y0 < 0 || y0 >= md->ys /*|| map_getcellp(md,x0,y0,cell)*/)
|
||||
if (x0 < 0 || x0 >= mapdata->xs || y0 < 0 || y0 >= mapdata->ys /*|| map_getcellp(mapdata,x0,y0,cell)*/)
|
||||
return false;
|
||||
|
||||
// Check destination cell
|
||||
if (x1 < 0 || x1 >= md->xs || y1 < 0 || y1 >= md->ys || map_getcellp(md,x1,y1,cell))
|
||||
if (x1 < 0 || x1 >= mapdata->xs || y1 < 0 || y1 >= mapdata->ys || map_getcellp(mapdata,x1,y1,cell))
|
||||
return false;
|
||||
|
||||
if (flag&1) {
|
||||
@ -318,7 +314,7 @@ bool path_search(struct walkpath_data *wpd, int16 m, int16 x0, int16 y0, int16 x
|
||||
|
||||
if( dx == 0 && dy == 0 )
|
||||
break; // success
|
||||
if( map_getcellp(md,x,y,cell) )
|
||||
if( map_getcellp(mapdata,x,y,cell) )
|
||||
break; // obstacle = failure
|
||||
}
|
||||
|
||||
@ -335,8 +331,8 @@ bool path_search(struct walkpath_data *wpd, int16 m, int16 x0, int16 y0, int16 x
|
||||
// Figure out more proper size or another way to keep track of known nodes.
|
||||
struct path_node tp[MAX_WALKPATH * MAX_WALKPATH];
|
||||
struct path_node *current, *it;
|
||||
int xs = md->xs - 1;
|
||||
int ys = md->ys - 1;
|
||||
int xs = mapdata->xs - 1;
|
||||
int ys = mapdata->ys - 1;
|
||||
int len = 0;
|
||||
int j;
|
||||
|
||||
@ -388,26 +384,26 @@ bool path_search(struct walkpath_data *wpd, int16 m, int16 x0, int16 y0, int16 x
|
||||
break;
|
||||
}
|
||||
|
||||
if (y < ys && !map_getcellp(md, x, y+1, cell)) allowed_dirs |= PATH_DIR_NORTH;
|
||||
if (y > 0 && !map_getcellp(md, x, y-1, cell)) allowed_dirs |= PATH_DIR_SOUTH;
|
||||
if (x < xs && !map_getcellp(md, x+1, y, cell)) allowed_dirs |= PATH_DIR_EAST;
|
||||
if (x > 0 && !map_getcellp(md, x-1, y, cell)) allowed_dirs |= PATH_DIR_WEST;
|
||||
if (y < ys && !map_getcellp(mapdata, x, y+1, cell)) allowed_dirs |= PATH_DIR_NORTH;
|
||||
if (y > 0 && !map_getcellp(mapdata, x, y-1, cell)) allowed_dirs |= PATH_DIR_SOUTH;
|
||||
if (x < xs && !map_getcellp(mapdata, x+1, y, cell)) allowed_dirs |= PATH_DIR_EAST;
|
||||
if (x > 0 && !map_getcellp(mapdata, x-1, y, cell)) allowed_dirs |= PATH_DIR_WEST;
|
||||
|
||||
#define chk_dir(d) ((allowed_dirs & (d)) == (d))
|
||||
// Process neighbors of current node
|
||||
if (chk_dir(PATH_DIR_SOUTH|PATH_DIR_EAST) && !map_getcellp(md, x+1, y-1, cell))
|
||||
if (chk_dir(PATH_DIR_SOUTH|PATH_DIR_EAST) && !map_getcellp(mapdata, x+1, y-1, cell))
|
||||
e += add_path(&g_open_set, tp, x+1, y-1, g_cost + MOVE_DIAGONAL_COST, current, heuristic(x+1, y-1, x1, y1)); // (x+1, y-1) 5
|
||||
if (chk_dir(PATH_DIR_EAST))
|
||||
e += add_path(&g_open_set, tp, x+1, y, g_cost + MOVE_COST, current, heuristic(x+1, y, x1, y1)); // (x+1, y) 6
|
||||
if (chk_dir(PATH_DIR_NORTH|PATH_DIR_EAST) && !map_getcellp(md, x+1, y+1, cell))
|
||||
if (chk_dir(PATH_DIR_NORTH|PATH_DIR_EAST) && !map_getcellp(mapdata, x+1, y+1, cell))
|
||||
e += add_path(&g_open_set, tp, x+1, y+1, g_cost + MOVE_DIAGONAL_COST, current, heuristic(x+1, y+1, x1, y1)); // (x+1, y+1) 7
|
||||
if (chk_dir(PATH_DIR_NORTH))
|
||||
e += add_path(&g_open_set, tp, x, y+1, g_cost + MOVE_COST, current, heuristic(x, y+1, x1, y1)); // (x, y+1) 0
|
||||
if (chk_dir(PATH_DIR_NORTH|PATH_DIR_WEST) && !map_getcellp(md, x-1, y+1, cell))
|
||||
if (chk_dir(PATH_DIR_NORTH|PATH_DIR_WEST) && !map_getcellp(mapdata, x-1, y+1, cell))
|
||||
e += add_path(&g_open_set, tp, x-1, y+1, g_cost + MOVE_DIAGONAL_COST, current, heuristic(x-1, y+1, x1, y1)); // (x-1, y+1) 1
|
||||
if (chk_dir(PATH_DIR_WEST))
|
||||
e += add_path(&g_open_set, tp, x-1, y, g_cost + MOVE_COST, current, heuristic(x-1, y, x1, y1)); // (x-1, y) 2
|
||||
if (chk_dir(PATH_DIR_SOUTH|PATH_DIR_WEST) && !map_getcellp(md, x-1, y-1, cell))
|
||||
if (chk_dir(PATH_DIR_SOUTH|PATH_DIR_WEST) && !map_getcellp(mapdata, x-1, y-1, cell))
|
||||
e += add_path(&g_open_set, tp, x-1, y-1, g_cost + MOVE_DIAGONAL_COST, current, heuristic(x-1, y-1, x1, y1)); // (x-1, y-1) 3
|
||||
if (chk_dir(PATH_DIR_SOUTH))
|
||||
e += add_path(&g_open_set, tp, x, y-1, g_cost + MOVE_COST, current, heuristic(x, y-1, x1, y1)); // (x, y-1) 4
|
||||
|
@ -4,7 +4,6 @@
|
||||
#include "pc.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
@ -713,9 +712,10 @@ void pc_makesavestatus(struct map_session_data *sd) {
|
||||
}
|
||||
|
||||
if(map_getmapflag(sd->bl.m, MF_NOSAVE)) {
|
||||
struct map_data *m=&map[sd->bl.m];
|
||||
if(m->save.map)
|
||||
memcpy(&sd->status.last_point,&m->save,sizeof(sd->status.last_point));
|
||||
struct map_data *mapdata = map_getmapdata(sd->bl.m);
|
||||
|
||||
if(mapdata->save.map)
|
||||
memcpy(&sd->status.last_point,&mapdata->save,sizeof(sd->status.last_point));
|
||||
else
|
||||
memcpy(&sd->status.last_point,&sd->status.save_point,sizeof(sd->status.last_point));
|
||||
}
|
||||
@ -1568,7 +1568,7 @@ void pc_reg_received(struct map_session_data *sd)
|
||||
sd->vd.class_ = JT_INVISIBLE;
|
||||
clif_displaymessage( sd->fd, msg_txt( sd, 11 ) ); // Invisible: On
|
||||
// decrement the number of pvp players on the map
|
||||
map[sd->bl.m].users_pvp--;
|
||||
map_getmapdata(sd->bl.m)->users_pvp--;
|
||||
|
||||
if( map_getmapflag(sd->bl.m, MF_PVP) && !map_getmapflag(sd->bl.m, MF_PVP_NOCALCRANK) && sd->pvp_timer != INVALID_TIMER ){
|
||||
// unregister the player for ranking
|
||||
@ -5496,6 +5496,8 @@ enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, in
|
||||
|
||||
m = map_mapindex2mapid(mapindex);
|
||||
|
||||
struct map_data *mapdata = map_getmapdata(m);
|
||||
|
||||
sd->state.changemap = (sd->mapindex != mapindex);
|
||||
sd->state.warping = 1;
|
||||
sd->state.workinprogress = WIP_DISABLE_NONE;
|
||||
@ -5503,7 +5505,7 @@ enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, in
|
||||
if( sd->state.changemap ) { // Misc map-changing settings
|
||||
int i;
|
||||
|
||||
if(map[sd->bl.m].instance_id && !map[m].instance_id) {
|
||||
if(map_getmapdata(sd->bl.m)->instance_id && !mapdata->instance_id) {
|
||||
bool instance_found = false;
|
||||
struct party_data *p = NULL;
|
||||
struct guild *g = NULL;
|
||||
@ -5599,7 +5601,7 @@ enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, in
|
||||
return SETPOS_OK;
|
||||
}
|
||||
|
||||
if( x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys )
|
||||
if( x < 0 || x >= mapdata->xs || y < 0 || y >= mapdata->ys )
|
||||
{
|
||||
ShowError("pc_setpos: attempt to place player '%s' (%d:%d) on invalid coordinates (%s-%d,%d)\n", sd->status.name, sd->status.account_id, sd->status.char_id, mapindex_id2name(mapindex),x,y);
|
||||
x = y = 0; // make it random
|
||||
@ -5608,11 +5610,11 @@ enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, in
|
||||
if( x == 0 && y == 0 ) { // pick a random walkable cell
|
||||
int c=0;
|
||||
do {
|
||||
x = rnd()%(map[m].xs-2)+1;
|
||||
y = rnd()%(map[m].ys-2)+1;
|
||||
x = rnd()%(mapdata->xs-2)+1;
|
||||
y = rnd()%(mapdata->ys-2)+1;
|
||||
c++;
|
||||
|
||||
if(c > (map[m].xs * map[m].ys)*3){ //force out
|
||||
if(c > (mapdata->xs * mapdata->ys)*3){ //force out
|
||||
ShowError("pc_setpos: couldn't found a valid coordinates for player '%s' (%d:%d) on (%s), preventing warp\n", sd->status.name, sd->status.account_id, sd->status.char_id, mapindex_id2name(mapindex));
|
||||
return SETPOS_OK; //preventing warp
|
||||
//break; //allow warp anyway
|
||||
@ -5696,22 +5698,21 @@ enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, in
|
||||
char pc_randomwarp(struct map_session_data *sd, clr_type type)
|
||||
{
|
||||
int x,y,i=0;
|
||||
int16 m;
|
||||
|
||||
nullpo_ret(sd);
|
||||
|
||||
m=sd->bl.m;
|
||||
|
||||
if (map_getmapflag(sd->bl.m, MF_NOTELEPORT)) //Teleport forbidden
|
||||
return 3;
|
||||
|
||||
struct map_data *mapdata = map_getmapdata(sd->bl.m);
|
||||
|
||||
do {
|
||||
x = rnd()%(map[m].xs-2)+1;
|
||||
y = rnd()%(map[m].ys-2)+1;
|
||||
} while((map_getcell(m,x,y,CELL_CHKNOPASS) || (!battle_config.teleport_on_portal && npc_check_areanpc(1,m,x,y,1))) && (i++) < 1000);
|
||||
x = rnd()%(mapdata->xs-2)+1;
|
||||
y = rnd()%(mapdata->ys-2)+1;
|
||||
} while((map_getcell(sd->bl.m,x,y,CELL_CHKNOPASS) || (!battle_config.teleport_on_portal && npc_check_areanpc(1,sd->bl.m,x,y,1))) && (i++) < 1000);
|
||||
|
||||
if (i < 1000)
|
||||
return pc_setpos(sd,map[sd->bl.m].index,x,y,type);
|
||||
return pc_setpos(sd,mapdata->index,x,y,type);
|
||||
|
||||
return 3;
|
||||
}
|
||||
@ -5756,7 +5757,7 @@ bool pc_memo(struct map_session_data* sd, int pos)
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
if( map[sd->bl.m].instance_id ) {
|
||||
if( map_getmapdata(sd->bl.m)->instance_id ) {
|
||||
clif_displaymessage( sd->fd, msg_txt(sd,384) ); // You cannot create a memo in an instance.
|
||||
return false;
|
||||
}
|
||||
@ -7972,9 +7973,9 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
|
||||
|
||||
if( map_getmapflag( sd->bl.m, MF_PVP_NIGHTMAREDROP ) ) { // Moved this outside so it works when PVP isn't enabled and during pk mode [Ancyker]
|
||||
for(int j=0;j<MAX_DROP_PER_MAP;j++){
|
||||
int id = map[sd->bl.m].drop_list[j].drop_id;
|
||||
int per = map[sd->bl.m].drop_list[j].drop_per;
|
||||
enum e_nightmare_drop_type type = map[sd->bl.m].drop_list[j].drop_type;
|
||||
int id = map_getmapdata(sd->bl.m)->drop_list[j].drop_id;
|
||||
int per = map_getmapdata(sd->bl.m)->drop_list[j].drop_per;
|
||||
enum e_nightmare_drop_type type = map_getmapdata(sd->bl.m)->drop_list[j].drop_type;
|
||||
|
||||
if(id == 0)
|
||||
continue;
|
||||
@ -10301,12 +10302,12 @@ static int pc_calc_pvprank_sub(struct block_list *bl,va_list ap)
|
||||
int pc_calc_pvprank(struct map_session_data *sd)
|
||||
{
|
||||
int old = sd->pvp_rank;
|
||||
struct map_data *m = &map[sd->bl.m];
|
||||
struct map_data *mapdata = map_getmapdata(sd->bl.m);
|
||||
|
||||
sd->pvp_rank=1;
|
||||
map_foreachinmap(pc_calc_pvprank_sub,sd->bl.m,BL_PC,sd);
|
||||
if(old!=sd->pvp_rank || sd->pvp_lastusers!=m->users_pvp)
|
||||
clif_pvpset(sd,sd->pvp_rank,sd->pvp_lastusers=m->users_pvp,0);
|
||||
if(old!=sd->pvp_rank || sd->pvp_lastusers!=mapdata->users_pvp)
|
||||
clif_pvpset(sd,sd->pvp_rank,sd->pvp_lastusers=mapdata->users_pvp,0);
|
||||
return sd->pvp_rank;
|
||||
}
|
||||
/*==========================================
|
||||
@ -12374,13 +12375,16 @@ void pc_show_questinfo(struct map_session_data *sd) {
|
||||
|
||||
if (sd->bl.m < 0 || sd->bl.m >= MAX_MAPINDEX)
|
||||
return;
|
||||
if (!map[sd->bl.m].qi_count || !map[sd->bl.m].qi_data)
|
||||
|
||||
struct map_data *mapdata = map_getmapdata(sd->bl.m);
|
||||
|
||||
if (!mapdata->qi_count || !mapdata->qi_data)
|
||||
return;
|
||||
if (map[sd->bl.m].qi_count != sd->qi_count)
|
||||
if (mapdata->qi_count != sd->qi_count)
|
||||
return; // init was not called yet
|
||||
|
||||
for(i = 0; i < map[sd->bl.m].qi_count; i++) {
|
||||
qi = &map[sd->bl.m].qi_data[i];
|
||||
for(i = 0; i < mapdata->qi_count; i++) {
|
||||
qi = &mapdata->qi_data[i];
|
||||
|
||||
if (!qi)
|
||||
continue;
|
||||
@ -12450,9 +12454,12 @@ void pc_show_questinfo_reinit(struct map_session_data *sd) {
|
||||
|
||||
if (sd->bl.m < 0 || sd->bl.m >= MAX_MAPINDEX)
|
||||
return;
|
||||
if (!map[sd->bl.m].qi_count || !map[sd->bl.m].qi_data)
|
||||
|
||||
struct map_data *mapdata = map_getmapdata(sd->bl.m);
|
||||
|
||||
if (!mapdata->qi_count || !mapdata->qi_data)
|
||||
return;
|
||||
CREATE(sd->qi_display, bool, (sd->qi_count = map[sd->bl.m].qi_count));
|
||||
CREATE(sd->qi_display, bool, (sd->qi_count = mapdata->qi_count));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -12470,7 +12477,9 @@ bool pc_job_can_entermap(enum e_job jobid, int m, int group_lv) {
|
||||
if (m < 0)
|
||||
return true;
|
||||
|
||||
if (m >= MAX_MAP_PER_SERVER || !map[m].cell)
|
||||
struct map_data *mapdata = map_getmapdata(m);
|
||||
|
||||
if (!mapdata->cell)
|
||||
return false;
|
||||
|
||||
if (!pcdb_checkid(jobid))
|
||||
@ -12485,7 +12494,7 @@ bool pc_job_can_entermap(enum e_job jobid, int m, int group_lv) {
|
||||
(map_flag_gvg2_no_te(m) && job_info[idx].noenter_map.zone&4) || // GVG
|
||||
(map_getmapflag(m, MF_BATTLEGROUND) && job_info[idx].noenter_map.zone&8) || // Battleground
|
||||
(map_flag_gvg2_te(m) && job_info[idx].noenter_map.zone&16) || // WOE:TE
|
||||
(map_getmapflag(m, MF_RESTRICTED) && job_info[idx].noenter_map.zone&(8*map[m].zone)) // Zone restriction
|
||||
(map_getmapflag(m, MF_RESTRICTED) && job_info[idx].noenter_map.zone&(8*mapdata->zone)) // Zone restriction
|
||||
)
|
||||
return false;
|
||||
|
||||
|
@ -490,16 +490,18 @@ static void script_reportsrc(struct script_state *st)
|
||||
if( bl == NULL )
|
||||
return;
|
||||
|
||||
struct map_data *mapdata = map_getmapdata(bl->m);
|
||||
|
||||
switch( bl->type ) {
|
||||
case BL_NPC:
|
||||
if( bl->m >= 0 )
|
||||
ShowDebug("Source (NPC): %s at %s (%d,%d)\n", ((struct npc_data *)bl)->name, map[bl->m].name, bl->x, bl->y);
|
||||
ShowDebug("Source (NPC): %s at %s (%d,%d)\n", ((struct npc_data *)bl)->name, mapdata->name, bl->x, bl->y);
|
||||
else
|
||||
ShowDebug("Source (NPC): %s (invisible/not on a map)\n", ((struct npc_data *)bl)->name);
|
||||
break;
|
||||
default:
|
||||
if( bl->m >= 0 )
|
||||
ShowDebug("Source (Non-NPC type %d): name %s at %s (%d,%d)\n", bl->type, status_get_name(bl), map[bl->m].name, bl->x, bl->y);
|
||||
ShowDebug("Source (Non-NPC type %d): name %s at %s (%d,%d)\n", bl->type, status_get_name(bl), mapdata->name, bl->x, bl->y);
|
||||
else
|
||||
ShowDebug("Source (Non-NPC type %d): name %s (invisible/not on a map)\n", bl->type, status_get_name(bl));
|
||||
break;
|
||||
@ -5604,7 +5606,7 @@ BUILDIN_FUNC(warpparty)
|
||||
if( !(pl_sd = p->data[i].sd) || pl_sd->status.party_id != p_id )
|
||||
continue;
|
||||
|
||||
if( str2 && strcmp(str2, map[pl_sd->bl.m].name) != 0 )
|
||||
if( str2 && strcmp(str2, map_getmapdata(pl_sd->bl.m)->name) != 0 )
|
||||
continue;
|
||||
|
||||
if( pc_isdead(pl_sd) )
|
||||
@ -8437,7 +8439,7 @@ BUILDIN_FUNC(strcharinfo)
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
script_pushconststr(st,map[sd->bl.m].name);
|
||||
script_pushconststr(st,map_getmapdata(sd->bl.m)->name);
|
||||
break;
|
||||
default:
|
||||
ShowWarning("buildin_strcharinfo: unknown parameter.\n");
|
||||
@ -8491,7 +8493,7 @@ BUILDIN_FUNC(strnpcinfo)
|
||||
break;
|
||||
case 4: // map name
|
||||
if (nd->bl.m >= 0)
|
||||
name = aStrdup(map[nd->bl.m].name);
|
||||
name = aStrdup(map_getmapdata(nd->bl.m)->name);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -10970,7 +10972,7 @@ BUILDIN_FUNC(getusers)
|
||||
|
||||
if(bl)
|
||||
{
|
||||
val = map[bl->m].users;
|
||||
val = map_getmapdata(bl->m)->users;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
@ -11028,7 +11030,7 @@ BUILDIN_FUNC(getmapusers)
|
||||
script_pushint(st,-1);
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
script_pushint(st,map[m].users);
|
||||
script_pushint(st,map_getmapdata(m)->users);
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
/*==========================================
|
||||
@ -14931,7 +14933,7 @@ BUILDIN_FUNC(getmapxy)
|
||||
|
||||
x= bl->x;
|
||||
y= bl->y;
|
||||
safestrncpy(mapname, map[bl->m].name, MAP_NAME_LENGTH);
|
||||
safestrncpy(mapname, map_getmapdata(bl->m)->name, MAP_NAME_LENGTH);
|
||||
|
||||
//Set MapName$
|
||||
num=st->stack->stack_data[st->start+2].u.num;
|
||||
@ -14987,7 +14989,7 @@ BUILDIN_FUNC(mapid2name)
|
||||
{
|
||||
uint16 m = script_getnum(st, 2);
|
||||
|
||||
if (m < 0 || m >= MAX_MAP_PER_SERVER) {
|
||||
if (m < 0) {
|
||||
script_pushconststr(st, "");
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
@ -19506,8 +19508,10 @@ BUILDIN_FUNC(bg_updatescore)
|
||||
if( (m = map_mapname2mapid(str)) < 0 )
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
|
||||
map[m].bgscore_lion = script_getnum(st,3);
|
||||
map[m].bgscore_eagle = script_getnum(st,4);
|
||||
struct map_data *mapdata = map_getmapdata(m);
|
||||
|
||||
mapdata->bgscore_lion = script_getnum(st,3);
|
||||
mapdata->bgscore_eagle = script_getnum(st,4);
|
||||
|
||||
clif_bg_updatescore(m);
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
@ -19643,7 +19647,7 @@ BUILDIN_FUNC(instance_destroy)
|
||||
else
|
||||
instance_id = script_instancegetid(st);
|
||||
|
||||
if( instance_id == 0 || instance_id >= MAX_MAP_PER_SERVER ) {
|
||||
if( instance_id == 0 ) {
|
||||
ShowError("buildin_instance_destroy: Trying to destroy invalid instance %hu.\n", instance_id);
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
@ -19733,7 +19737,7 @@ BUILDIN_FUNC(instance_mapname)
|
||||
if(!instance_id || (m = instance_mapname2mapid(str,instance_id)) < 0)
|
||||
script_pushconststr(st, "");
|
||||
else
|
||||
script_pushconststr(st, map[m].name);
|
||||
script_pushconststr(st, map_getmapdata(m)->name);
|
||||
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
@ -19807,7 +19811,7 @@ BUILDIN_FUNC(instance_warpall)
|
||||
else
|
||||
instance_id = script_instancegetid(st);
|
||||
|
||||
if( !instance_id || (m = map_mapname2mapid(mapn)) < 0 || (m = instance_mapname2mapid(map[m].name,instance_id)) < 0)
|
||||
if( !instance_id || (m = map_mapname2mapid(mapn)) < 0 || (m = instance_mapname2mapid(map_getmapdata(m)->name,instance_id)) < 0)
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
|
||||
for(i = 0; i < instance_data[instance_id].cnt_map; i++)
|
||||
@ -22964,7 +22968,7 @@ BUILDIN_FUNC(channel_chat) {
|
||||
script_pushint(st,0);
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
if (!(ch = map[m].channel)) {
|
||||
if (!(ch = map_getmapdata(m)->channel)) {
|
||||
ShowDebug("buildin_channel_chat: Map '%s' doesn't have local channel yet.\n", chname);
|
||||
script_pushint(st,0);
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
@ -22977,7 +22981,7 @@ BUILDIN_FUNC(channel_chat) {
|
||||
script_pushint(st,0);
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
if (!(ch = map[nd->bl.m].channel)) {
|
||||
if (!(ch = map_getmapdata(nd->bl.m)->channel)) {
|
||||
ShowDebug("buildin_channel_chat: Map '%s' doesn't have local channel yet.\n", chname);
|
||||
script_pushint(st,0);
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
|
@ -700,7 +700,7 @@ bool skill_isNotOk(uint16 skill_id, struct map_session_data *sd)
|
||||
(map_flag_gvg2_no_te(m) && skill_nocast&4) ||
|
||||
(map_getmapflag(m, MF_BATTLEGROUND) && skill_nocast&8) ||
|
||||
(map_flag_gvg2_te(m) && skill_nocast&16) || // WOE:TE
|
||||
(map_getmapflag(m, MF_RESTRICTED) && map[m].zone && skill_nocast&(8*map[m].zone)) ){
|
||||
(map_getmapflag(m, MF_RESTRICTED) && map_getmapdata(m)->zone && skill_nocast&(8*map_getmapdata(m)->zone)) ){
|
||||
clif_msg(sd, SKILL_CANT_USE_AREA); // This skill cannot be used within this area
|
||||
return true;
|
||||
}
|
||||
@ -13076,9 +13076,10 @@ struct skill_unit_group *skill_unitsetting(struct block_list *src, uint16 skill_
|
||||
int unit_val1 = skill_lv;
|
||||
int unit_val2 = 0;
|
||||
int alive = 1;
|
||||
struct map_data *mapdata = map_getmapdata(src->m);
|
||||
|
||||
// are the coordinates out of range?
|
||||
if( ux <= 0 || uy <= 0 || ux >= map[src->m].xs || uy >= map[src->m].ys ){
|
||||
if( ux <= 0 || uy <= 0 || ux >= mapdata->xs || uy >= mapdata->ys ){
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,7 @@ static unsigned int status_calc_maxhpsp_pc(struct map_session_data* sd, unsigned
|
||||
static int status_get_sc_interval(enum sc_type type);
|
||||
|
||||
static bool status_change_isDisabledOnMap_(sc_type type, bool mapIsVS, bool mapIsPVP, bool mapIsGVG, bool mapIsBG, unsigned int mapZone, bool mapIsTE);
|
||||
#define status_change_isDisabledOnMap(type, m) ( status_change_isDisabledOnMap_((type), map_flag_vs2((m)), map_getmapflag((m), MF_PVP) != 0, map_flag_gvg2_no_te((m)), map_getmapflag((m), MF_BATTLEGROUND) != 0, (map[(m)].zone << 3) != 0, map_flag_gvg2_te((m))) )
|
||||
#define status_change_isDisabledOnMap(type, m) ( status_change_isDisabledOnMap_((type), map_flag_vs2((m)), map_getmapflag((m), MF_PVP) != 0, map_flag_gvg2_no_te((m)), map_getmapflag((m), MF_BATTLEGROUND) != 0, (map_getmapdata(m)->zone << 3) != 0, map_flag_gvg2_te((m))) )
|
||||
|
||||
/**
|
||||
* Returns the status change associated with a skill.
|
||||
@ -2801,10 +2801,11 @@ int status_calc_mob_(struct mob_data* md, enum e_status_calc_opt opt)
|
||||
|
||||
if(flag&4) { // Strengthen Guardians - custom value +10% / lv
|
||||
struct guild_castle *gc;
|
||||
struct map_data *mapdata = map_getmapdata(md->bl.m);
|
||||
|
||||
gc=guild_mapname2gc(map[md->bl.m].name);
|
||||
gc=guild_mapname2gc(mapdata->name);
|
||||
if (!gc)
|
||||
ShowError("status_calc_mob: No castle set at map %s\n", map[md->bl.m].name);
|
||||
ShowError("status_calc_mob: No castle set at map %s\n", mapdata->name);
|
||||
else if(gc->castle_id < 24 || md->mob_id == MOBID_EMPERIUM) {
|
||||
#ifdef RENEWAL
|
||||
status->max_hp += 50 * (gc->defense / 5);
|
||||
@ -14373,7 +14374,7 @@ void status_change_clear_onChangeMap(struct block_list *bl, struct status_change
|
||||
bool mapIsGVG = map_flag_gvg2_no_te(bl->m);
|
||||
bool mapIsBG = map_getmapflag(bl->m, MF_BATTLEGROUND) != 0;
|
||||
bool mapIsTE = map_flag_gvg2_te(bl->m);
|
||||
unsigned int mapZone = map[bl->m].zone << 3;
|
||||
unsigned int mapZone = map_getmapdata(bl->m)->zone << 3;
|
||||
|
||||
for (i = 0; i < SC_MAX; i++) {
|
||||
if (!sc->data[i] || !SCDisabled[i])
|
||||
|
@ -369,7 +369,7 @@ int8 vending_openvending(struct map_session_data* sd, const char* message, const
|
||||
|
||||
if( Sql_Query( mmysql_handle, "INSERT INTO `%s`(`id`, `account_id`, `char_id`, `sex`, `map`, `x`, `y`, `title`, `autotrade`, `body_direction`, `head_direction`, `sit`) "
|
||||
"VALUES( %d, %d, %d, '%c', '%s', %d, %d, '%s', %d, '%d', '%d', '%d' );",
|
||||
vendings_table, sd->vender_id, sd->status.account_id, sd->status.char_id, sd->status.sex == SEX_FEMALE ? 'F' : 'M', map[sd->bl.m].name, sd->bl.x, sd->bl.y, message_sql, sd->state.autotrade, at ? at->dir : sd->ud.dir, at ? at->head_dir : sd->head_dir, at ? at->sit : pc_issit(sd) ) != SQL_SUCCESS ) {
|
||||
vendings_table, sd->vender_id, sd->status.account_id, sd->status.char_id, sd->status.sex == SEX_FEMALE ? 'F' : 'M', map_getmapdata(sd->bl.m)->name, sd->bl.x, sd->bl.y, message_sql, sd->state.autotrade, at ? at->dir : sd->ud.dir, at ? at->head_dir : sd->head_dir, at ? at->sit : pc_issit(sd) ) != SQL_SUCCESS ) {
|
||||
Sql_ShowDebug(mmysql_handle);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user