Kaynağa Gözat

-Follow up r17332
--Fix unreference warning and delete_timer mismatch func
-- updated all map_msg translations and edited some comments. (Euphy)
-Merge/adapt few Hercules stuff:
-- Add save char after buying if save_config&128
-- Check if char_server online before sending 0x3008 (stats_report)
-- Add hom_class2type, to solve homonculus type, easier then bitmasking.
-- Add vending_db to speed up searchstore iteration.
-Quickfix (Daegaladh)
--Add emotion effect to SA_QUESTION
--Upd SA_INSTANTDEATH to really kill ourself and not set to 1hp
--Fix SC_SLOWDOWN not asking to recalculate speed when used.
--Fix SC_STRIPX effect on player, (should only remove equip on player)

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@17333 54d463be-8e91-2dee-dedb-b68131a5f0ec

glighta 12 yıl önce
ebeveyn
işleme
02ddefb9d5

+ 2 - 2
conf/msg_conf/map_msg.conf

@@ -868,7 +868,7 @@
 1042: Town Map
 1043: Autotrade Enabled
 1044: Autotrade Disabled
-1045: Battlegrounds ON type=%d
+1045: Battlegrounds ON (type %d)
 1046: PvP Flags:
 1047: Pvp ON |
 1048: NoGuild |
@@ -929,7 +929,7 @@
 1103: nosumstarmiracle |
 1104: nomineeffect |
 1105: nolockon |
-1106: Restricted zone=%d
+1106: Restricted (zone %d)
 
 // @mount
 1119: You have mounted your Dragon.

+ 31 - 23
conf/msg_conf/map_msg_chn.conf

@@ -444,9 +444,29 @@
 463: 訊息組態已被重新載入
 464: ---- 允許的語言:
 
+480: ----- Players in Map -----
+481: Player '%s' (session #%d) | Location: %d,%d
+482: ----- NPCs in Map -----
+483: ----- Chats in Map -----
+484: Chat: %s | Player: %s | Location: %d %d
+485:    Users: %d/%d | Password: %s | Public: %s
+486: Yes
+487: No
+488: Please enter at least one valid list number (用法: @mapinfo <0-3> <map>).
+489: NPC %d: %s::%s | Direction: %s | Sprite: %d | Location: %d %d
+490: NPC %d: %s | Direction: %s | Sprite: %d | Location: %d %d
+491: North
+492: North West
+493: West
+494: South West
+495: South
+496: South East
+497: East
+498: North East
+499: Unknown
+
 // Messages of others (not for GM commands)
 // ----------------------------------------
-
 //500 free
 501: 您上次登入時間是: %d-%m-%Y %H:%M:%S
 502: 白晝到來了
@@ -841,7 +861,7 @@
 1042: Town Map
 1043: Autotrade Enabled
 1044: Autotrade Disabled
-1045: Battlegrounds ON
+1045: Battlegrounds ON (type %d)
 1046: PvP Flags: 
 1047: Pvp ON | 
 1048: NoGuild | 
@@ -894,27 +914,15 @@
 1095: NoMVPLoot | 
 1096: PartyLock | 
 1097: GuildLock | 
-1098: ----- Players in Map -----
-1099: Player '%s' (session #%d) | Location: %d,%d
-1100: ----- NPCs in Map -----
-1101: North
-1102: North West
-1103: West
-1104: South West
-1105: South
-1106: South East
-1107: East
-1108: North East
-1109: North
-1110: Unknown
-1111: NPC %d: %s | Direction: %s | Sprite: %d | Location: %d %d
-1112: NPC %d: %s::%s | Direction: %s | Sprite: %d | Location: %d %d 
-1113: ----- Chats in Map -----
-1114: Chat: %s | Player: %s | Location: %d %d
-1115:    Users: %d/%d | Password: %s | Public: %s
-1116: Yes
-1117: No
-1118: Please enter at least one valid list number (用法: @mapinfo <0-3> <map>).
+1098: Loadevent |
+1099: Src4instance |
+1100: Chmautojoin |
+1101: nousecart |
+1102: noitemconsumption |
+1103: nosumstarmiracle |
+1104: nomineeffect |
+1105: nolockon |
+1106: Restricted (zone %d)
 
 // @mount
 1119: You have mounted your Dragon.

+ 31 - 23
conf/msg_conf/map_msg_frn.conf

@@ -450,9 +450,29 @@
 463: Configuration des messages rechargée.
 464: ---- Langues disponibles:
 
+480: ----- Joueurs sur la Map -----
+481: Joueur '%s' (session #%d) | Localisation: %d,%d
+482: ----- NPCs sur la Map -----
+483: ----- Chats sur la Map -----
+484: Chat: %s | Joueur: %s | Localisation: %d %d
+485:    Utilisateur: %d/%d | Mot de Passe: %s | Publique: %s
+486: Oui
+487: Non
+488: Entrez au moins un numéro de liste valide (usage: @mapinfo <0-3> <map>).
+489: NPC %d: %s::%s | Direction: %s | Sprite: %d | Localisation: %d %d
+490: NPC %d: %s | Direction: %s | Sprite: %d | Localisation: %d %d
+491: Nord
+492: Nord Ouest
+493: Ouest
+494: South Ouest
+495: South
+496: South Est
+497: Est
+498: Nord Est
+499: Inconnue
+
 // Autres Messages ( != GM commands)
 // ----------------------------------------
-
 //500 free
 501: La date limite de votre compte est: %d-%m-%Y %H:%M:%S.
 502: Le Mode Jour s'est activé
@@ -847,7 +867,7 @@
 1042: Town Map
 1043: Autotrade Activé
 1044: Autotrade Désactivé
-1045: Battlegrounds ON
+1045: Battlegrounds ON (type %d)
 1046: PvP Flags: 
 1047: Pvp ON | 
 1048: Noguild | 
@@ -900,27 +920,15 @@
 1095: NoMVPLoot | 
 1096: PartyLock | 
 1097: GuildLock | 
-1098: ----- Joueurs sur la Map -----
-1099: Joueur '%s' (session #%d) | Localisation: %d,%d
-1100: ----- NPCs sur la Map -----
-1101: Nord
-1102: Nord Ouest
-1103: Ouest
-1104: South Ouest
-1105: South
-1106: South Est
-1107: Est
-1108: Nord Est
-1109: Nord
-1110: Inconnue
-1111: NPC %d: %s | Direction: %s | Sprite: %d | Localisation: %d %d
-1112: NPC %d: %s::%s | Direction: %s | Sprite: %d | Localisation: %d %d 
-1113: ----- Chats sur la Map -----
-1114: Chat: %s | Joueur: %s | Localisation: %d %d
-1115:    Utilisateur: %d/%d | Mot de Passe: %s | Publique: %s
-1116: Oui
-1117: Non
-1118: Entrez au moins un numéro de liste valide (usage: @mapinfo <0-3> <map>).
+1098: Loadevent |
+1099: Src4instance |
+1100: Chmautojoin |
+1101: nousecart |
+1102: noitemconsumption |
+1103: nosumstarmiracle |
+1104: nomineeffect |
+1105: nolockon |
+1106: Restricted (zone %d)
 
 // @mount
 1119: Dragon monté.

+ 31 - 23
conf/msg_conf/map_msg_idn.conf

@@ -449,9 +449,29 @@
 463: Pengaturan bahasa telah dimuat ulang.
 464: ---- Bahasa yang tersedia:
 
+480: ----- Player yang ada di Map -----
+481: Player '%s' (sesi #%d) | Lokasi: %d,%d
+482: ----- NPC yang ada di Map -----
+483: ----- Ruang Chat yang ada di Map -----
+484: Chat: %s | Player: %s | Lokasi: %d %d
+485:    User: %d/%d | Password: %s | Publik: %s
+486: Ya
+487: Tidak
+488: Harap masukkan setidaknya 1 opsi (Penggunaan: @mapinfo <0-3> <map>).
+489: NPC %d: %s::%s | Arah: %s | Sprite: %d | Lokasi: %d %d
+490: NPC %d: %s | Arah: %s | Sprite: %d | Lokasi: %d %d
+491: Utara
+492: Barat Laut
+493: Barat
+494: Barat Daya
+495: Selatan
+496: Tenggara
+497: Timur
+498: Timur Laut
+499: Tidak diketahui
+
 // Pesan-pesan untuk keperluan lain (Bukan untuk perintah GM)
 // ----------------------------------------
-
 //500 kosong
 501: Batas akun kamu adalah: %d-%m-%Y %H:%M:%S.
 502: Mode siang diaktifkan.
@@ -846,7 +866,7 @@
 1042: Kota
 1043: Autotrade diaktifkan
 1044: Autotrade dinonaktifkan
-1045: Battleground ON
+1045: Battleground ON (tipe %d)
 1046: PvP Flags: 
 1047: Pvp ON | 
 1048: NoGuild | 
@@ -899,27 +919,15 @@
 1095: NoMVPLoot | 
 1096: PartyLock | 
 1097: GuildLock | 
-1098: ----- Player yang ada di Map -----
-1099: Player '%s' (sesi #%d) | Lokasi: %d,%d
-1100: ----- NPC yang ada di Map -----
-1101: Utara
-1102: Barat Laut
-1103: Barat
-1104: Barat Daya
-1105: Selatan
-1106: Tenggara
-1107: Timur
-1108: Timur Laut
-1109: Utara
-1110: Tidak diketahui
-1111: NPC %d: %s | Arah: %s | Sprite: %d | Lokasi: %d %d
-1112: NPC %d: %s::%s | Arah: %s | Sprite: %d | Lokasi: %d %d 
-1113: ----- Ruang Chat yang ada di Map -----
-1114: Chat: %s | Player: %s | Lokasi: %d %d
-1115:    User: %d/%d | Password: %s | Publik: %s
-1116: Ya
-1117: Tidak
-1118: Harap masukkan setidaknya 1 opsi (Penggunaan: @mapinfo <0-3> <map>).
+1098: Loadevent |
+1099: Src4instance |
+1100: Chmautojoin |
+1101: nousecart |
+1102: noitemconsumption |
+1103: nosumstarmiracle |
+1104: nomineeffect |
+1105: nolockon |
+1106: Restricted (zone %d)
 
 // @mount
 1119: Kamu sudah menaiki seekor naga.

+ 31 - 23
conf/msg_conf/map_msg_por.conf

@@ -449,9 +449,29 @@
 463: As configurações de mensagens foram recarregadas.
 464: ---- Idiomas disponíveis:
 
+480: ----- Jogadores no Mapa -----
+481: Jogador '%s' (sessão #%d) | Localização: %d,%d
+482: ----- NPCs no Mapa -----
+483: ----- Chats no Map -----
+484: Chat: %s | Jogador: %s | Localização: %d %d
+485:    Usuários: %d/%d | Senha: %s | Público: %s
+486: Sim
+487: Não
+488: Digite pelo menos um número válido da lista (uso: @mapinfo <0-3> <mapa>).
+489: NPC %d: %s::%s | Direção: %s | Sprite: %d | Localização: %d %d
+490: NPC %d: %s | Direção: %s | Sprite: %d | Localização: %d %d
+491: Norte
+492: Noroeste
+493: Oeste
+494: Sudoeste
+495: Sul
+496: Sudeste
+497: Leste
+498: Nordeste
+499: Desconhecido
+
 // Mensagens para outros (não para comandos de Game Master)
 // ----------------------------------------
-
 //500 livre
 501: A sua conta expira em: %d-%m-%Y %H:%M:%S.
 502: Está de dia
@@ -840,7 +860,7 @@
 1042: Mapa de Cidade
 1043: Autotrade Habilitado
 1044: Autotrade Desabilitado
-1045: Battlegrounds Habilitado
+1045: Battlegrounds Habilitado (tipo %d)
 1046: Flags de PvP: 
 1047: Pvp Habilitado | 
 1048: NoGuild | 
@@ -893,27 +913,15 @@
 1095: NoMVPLoot | 
 1096: PartyLock | 
 1097: GuildLock | 
-1098: ----- Jogadores no Mapa -----
-1099: Jogador '%s' (sessão #%d) | Localização: %d,%d
-1100: ----- NPCs no Mapa -----
-1101: Norte
-1102: Noroeste
-1103: Oeste
-1104: Sudoeste
-1105: Sul
-1106: Sudeste
-1107: Leste
-1108: Nordeste
-1109: Norte
-1110: Desconhecido
-1111: NPC %d: %s | Direção: %s | Sprite: %d | Localização: %d %d
-1112: NPC %d: %s::%s | Direção: %s | Sprite: %d | Localização: %d %d 
-1113: ----- Chats no Map -----
-1114: Chat: %s | Jogador: %s | Localização: %d %d
-1115:    Usuários: %d/%d | Senha: %s | Público: %s
-1116: Sim
-1117: Não
-1118: Digite pelo menos um número válido da lista (uso: @mapinfo <0-3> <mapa>).
+1098: Loadevent |
+1099: Src4instance |
+1100: Chmautojoin |
+1101: nousecart |
+1102: noitemconsumption |
+1103: nosumstarmiracle |
+1104: nomineeffect |
+1105: nolockon |
+1106: Restricted (zone %d)
 
 // @mount
 1119: Você montou um Dragão.

+ 31 - 22
conf/msg_conf/map_msg_rus.conf

@@ -453,6 +453,27 @@
 463: Файлы сообщений перезагружены.
 464: ---- Доступные языки:
 
+480: ----- Игроки на локации -----
+481: Игрок '%s' (сессия #%d) | Локация: %d,%d
+482: ----- НИП на локации---
+483: ----- Чаты на локации -----
+484: Чат: %s | Персонажи: %s | Локация: %d %d
+485:    Игроки: %d/%d | Пароль: %s | Публичный: %s
+486: Да
+487: Нет
+488: Введите хотя бы один номер (Использование: @mapinfo <0-3> <локация>).
+489: НИП %d: %s::%s | Направление: %s | Спрайт: %d | Локация: %d %d
+490: НИП %d: %s | Направление: %s | Спрайт: %d | Локация: %d %d
+491: Север
+492: Северо-Запад
+493: Запад
+494: Юго-Запад
+495: Юг
+496: Юго-Восток
+497: Восток
+498: Северо-Восток
+499: Неизвестно
+
 // ----------------------------------------
 // Остальные сообщения
 // ----------------------------------------
@@ -847,7 +868,7 @@
 1042: Столица
 1043: Autotrade Разрешён
 1044: Autotrade Запрещён
-1045: Battlegrounds ВКЛЮЧЕНО
+1045: Battlegrounds ВКЛЮЧЕНО (тип %d)
 1046: PvP флаги: 
 1047: Pvp ВКЛЮЧЕНО | 
 1048: NoGuild | 
@@ -900,27 +921,15 @@
 1095: NoMVPLoot | 
 1096: PartyLock | 
 1097: GuildLock | 
-1098: ----- Игроки на локации -----
-1099: Игрок '%s' (сессия #%d) | Локация: %d,%d
-1100: ----- НИП на локации---
-1101: Север
-1102: Северо-Запад
-1103: Запад
-1104: Юго-Запад
-1105: Юг
-1106: Юго-Восток
-1107: Восток
-1108: Северо-Восток
-1109: Север
-1110: Неизвестно
-1111: НИП %d: %s | Направление: %s | Спрайт: %d | Локация: %d %d
-1112: НИП %d: %s::%s | Направление: %s | Спрайт: %d | Локация: %d %d 
-1113: ----- Чаты на локации -----
-1114: Чат: %s | Персонажи: %s | Локация: %d %d
-1115:    Игроки: %d/%d | Пароль: %s | Публичный: %s
-1116: Да
-1117: Нет
-1118: Введите хотя бы один номер (Использование: @mapinfo <0-3> <локация>).
+1098: Loadevent |
+1099: Src4instance |
+1100: Chmautojoin |
+1101: nousecart |
+1102: noitemconsumption |
+1103: nosumstarmiracle |
+1104: nomineeffect |
+1105: nolockon |
+1106: Restricted (zone %d)
 
 // @mount
 1119: Вы оседлали Дракона.

+ 31 - 23
conf/msg_conf/map_msg_spn.conf

@@ -450,9 +450,29 @@
 463: Se ha actualizado la configuración de los mensajes.
 464: ---- Idiomas disponibles:
 
+480: ----- Jugadores en el mapa -----
+481: Jugador '%s' (sesión #%d) | Ubicación: %d,%d
+482: ----- NPCs en el mapa -----
+483: ----- Chats en el mapa -----
+484: Chat: %s | Jugador: %s | Ubicación: %d %d
+485:    Usuarios: %d/%d | Contraseña: %s | Abierto: %s
+486: Sí
+487: No
+488: Introduce un valor de la lista (Instrucciones: @mapinfo <0-3> <mapa>).
+489: NPC %d: %s::%s | Dirección: %s | Sprite: %d | Ubicación: %d %d
+490: NPC %d: %s | Dirección: %s | Sprite: %d | Ubicación: %d %d
+491: Norte
+492: Noroeste
+493: Oeste
+494: Sudoeste
+495: Sur
+496: Sudeste
+497: Este
+498: Nordeste
+499: Desconocido
+
 // Otros mensajes (no son de comandos de GM)
 // ----------------------------------------
-
 //500 vacío
 501: El límite de tiempo para tu cuenta es: %d-%m-%Y %H:%M:%S.
 502: Está activado el modo diurno.
@@ -847,7 +867,7 @@
 1042: Mapa de ciudad
 1043: Autotrade activado
 1044: Autotrade desactivado
-1045: Battleground activado
+1045: Battleground activado (tipo %d)
 1046: Configuración de PvP:
 1047: PvP activado |
 1048: Sin clan |
@@ -900,27 +920,15 @@
 1095: Sin objetos de MVP |
 1096: Bloqueo de grupos |
 1097: Bloqueo de clanes |
-1098: ----- Jugadores en el mapa -----
-1099: Jugador '%s' (sesión #%d) | Ubicación: %d,%d
-1100: ----- NPCs en el mapa -----
-1101: Norte
-1102: Noroeste
-1103: Oeste
-1104: Sudoeste
-1105: Sur
-1106: Sudeste
-1107: Este
-1108: Nordeste
-1109: Norte
-1110: Desconocido
-1111: NPC %d: %s | Dirección: %s | Sprite: %d | Ubicación: %d %d
-1112: NPC %d: %s::%s | Dirección: %s | Sprite: %d | Ubicación: %d %d
-1113: ----- Chats en el mapa -----
-1114: Chat: %s | Jugador: %s | Ubicación: %d %d
-1115:    Usuarios: %d/%d | Contraseña: %s | Abierto: %s
-1116: Sí
-1117: No
-1118: Introduce un valor de la lista (Instrucciones: @mapinfo <0-3> <mapa>).
+1098: Loadevent |
+1099: Src4instance |
+1100: Chmautojoin |
+1101: nousecart |
+1102: noitemconsumption |
+1103: nosumstarmiracle |
+1104: nomineeffect |
+1105: nolockon |
+1106: Restricted (zone %d)
 
 // @mount
 1119: Te has montado en tu dragón.

+ 5 - 7
src/char/char.c

@@ -1919,10 +1919,9 @@ int mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p)
 	return 106+offset;
 }
 
-
-
+//----------------------------------------
 // Tell client how many pages, kRO sends 17 (Yommy)
-
+//----------------------------------------
 void char_charlist_notify( int fd, struct char_session_data* sd ){
 	WFIFOHEAD(fd, 6);
 	WFIFOW(fd, 0) = 0x9a0;
@@ -1938,7 +1937,6 @@ void char_block_character( int fd, struct char_session_data* sd ){
 	WFIFOSET(fd,4);
 }
 
-/* Made Possible by Yommy~! <3 */
 void mmo_char_send099d(int fd, struct char_session_data *sd) {
 	WFIFOHEAD(fd,4 + (MAX_CHARS*MAX_CHAR_BUF));
 	WFIFOW(fd,0) = 0x99d;
@@ -1997,13 +1995,13 @@ void mmo_char_send082d(int fd, struct char_session_data* sd) {
 }
 
 void mmo_char_send(int fd, struct char_session_data* sd){
-    #if PACKETVER >= 20130000
+#if PACKETVER >= 20130000
 	mmo_char_send082d(fd,sd);
 	char_charlist_notify(fd,sd);
 	char_block_character(fd,sd);
-    #else
+#else
 	mmo_char_send006b(fd,sd);
-    #endif
+#endif
 }
 
 int char_married(int pl1, int pl2)

+ 1 - 1
src/common/mapindex.c

@@ -168,7 +168,7 @@ void mapindex_init(void) {
 	fclose(fp);
 
 	if( !strdb_iget(mapindex_db, MAP_DEFAULT) ) {
-		ShowError("mapindex_init: MAP_DEFAULT '%s' not found in cache! update mapindex.h MAP_DEFAULT var!!!\n",MAP_DEFAULT);
+		ShowError("mapindex_init: MAP_DEFAULT '%s' not found in cache! Update MAP_DEFAULT in mapindex.h!\n",MAP_DEFAULT);
 	}
 }
 

+ 1 - 1
src/common/mapindex.h

@@ -47,7 +47,7 @@ extern char mapindex_cfgfile[80];
 #define MAP_MALAYA "malaya"
 #define MAP_ECLAGE "eclage"
 
-// When a map index search fails, return results from what map? default:prontera
+// When a map index search fails, return results from what map?
 #define MAP_DEFAULT MAP_PRONTERA
 #define MAP_DEFAULT_X 150
 #define MAP_DEFAULT_Y 150

+ 4 - 4
src/map/atcommand.c

@@ -3773,8 +3773,8 @@ ACMD_FUNC(mapinfo) {
 	if (map[m_id].flag.town)
 		clif_displaymessage(fd, msg_txt(sd,1042)); // Town Map
 	if (map[m_id].flag.restricted){
-		sprintf(atcmd_output, msg_txt(sd,1106),map[m_id].zone);
-		clif_displaymessage(fd, atcmd_output); //restricted
+		sprintf(atcmd_output, msg_txt(sd,1106),map[m_id].zone); // Restricted (zone %d)
+		clif_displaymessage(fd, atcmd_output);
 	}
 
 	if (battle_config.autotrade_mapflag == map[m_id].flag.autotrade)
@@ -3783,8 +3783,8 @@ ACMD_FUNC(mapinfo) {
 		clif_displaymessage(fd, msg_txt(sd,1044)); // Autotrade Disabled
 
 	if (map[m_id].flag.battleground){
-		sprintf(atcmd_output, msg_txt(sd,1106),map[m_id].zone);
-		clif_displaymessage(fd, atcmd_output); // Battlegrounds ON type=%d
+		sprintf(atcmd_output, msg_txt(sd,1045),map[m_id].flag.battleground); // Battlegrounds ON (type %d)
+		clif_displaymessage(fd, atcmd_output);
 	}
 	strcpy(atcmd_output,msg_txt(sd,1046)); // PvP Flags:
 	if (map[m_id].flag.pvp)

+ 6 - 0
src/map/buyingstore.c

@@ -12,6 +12,7 @@
 #include "clif.h"  // clif_buyingstore_*
 #include "log.h"  // log_pick_pc, log_zeny
 #include "pc.h"  // struct map_session_data
+#include "chrif.h"
 
 
 /// constants (client-side restrictions)
@@ -379,6 +380,11 @@ void buyingstore_trade(struct map_session_data* sd, int account_id, unsigned int
 		clif_buyingstore_update_item(pl_sd, nameid, amount);
 	}
 
+	if( save_settings&128 ) {
+		chrif_save(sd, 0);
+		chrif_save(pl_sd, 0);
+	}
+	
 	// check whether or not there is still something to buy
 	ARR_FIND( 0, pl_sd->buyingstore.slots, i, pl_sd->buyingstore.items[i].amount != 0 );
 	if( i == pl_sd->buyingstore.slots )

+ 4 - 3
src/map/chrif.c

@@ -1550,16 +1550,17 @@ int chrif_removefriend(int char_id, int friend_id) {
 	return 0;
 }
 
-void chrif_send_report(char* buf, int len) {
+int chrif_send_report(char* buf, int len) {
 
 #ifndef STATS_OPT_OUT
+	chrif_check(-1);
 	WFIFOHEAD(char_fd,len + 2);
 	WFIFOW(char_fd,0) = 0x3008;
 	memcpy(WFIFOP(char_fd,2), buf, len);
 	WFIFOSET(char_fd,len + 2);
 	flush_fifo(char_fd); /* ensure it's sent now. */
 #endif
-
+	return 0;
 }
 
 /**
@@ -1601,7 +1602,7 @@ int do_final_chrif(void) {
  *------------------------------------------*/
 int do_init_chrif(void) {
 	if(sizeof(struct mmo_charstatus) > 0xFFFF){
-		ShowError("mmo_charstatus size = %d is too big to be transmit\n",
+		ShowError("mmo_charstatus size = %d is too big to be transmitted.\n",
 			sizeof(struct mmo_charstatus));
 		exit(EXIT_FAILURE);
 	}

+ 1 - 1
src/map/chrif.h

@@ -59,7 +59,7 @@ int chrif_chardisconnect(struct map_session_data *sd);
 int chrif_divorce(int partner_id1, int partner_id2);
 
 int chrif_removefriend(int char_id, int friend_id);
-void chrif_send_report(char* buf, int len);
+int chrif_send_report(char* buf, int len);
 
 int do_final_chrif(void);
 int do_init_chrif(void);

+ 16 - 8
src/map/clif.c

@@ -1378,12 +1378,12 @@ void clif_hominfo(struct map_session_data *sd, struct homun_data *hd, int flag)
 {
 	struct status_data *status;
 	unsigned char buf[128];
-	int m_class;
+	int htype;
 
 	nullpo_retv(hd);
 
 	status  = &hd->battle_status;
-	m_class = hom_class2mapid(hd->homunculus.class_);
+	htype = hom_class2type(hd->homunculus.class_);
 
 	memset(buf,0,packet_len(0x22e));
 	WBUFW(buf,0)=0x22e;
@@ -1420,10 +1420,18 @@ void clif_hominfo(struct map_session_data *sd, struct homun_data *hd, int flag)
 		WBUFW(buf,57)=status->max_sp;
 	}
 	WBUFL(buf,59)=hd->homunculus.exp;
-	if( ((m_class&HOM_REG) && hd->homunculus.level >= battle_config.hom_max_level) || ((m_class&HOM_S) && hd->homunculus.level >= battle_config.hom_S_max_level) )
-		WBUFL(buf,63)=0;
-	else
-		WBUFL(buf,63)=hd->exp_next;
+	WBUFL(buf,63)=hd->exp_next;
+	switch( htype ) {
+		case HT_REG:
+		case HT_EVO:
+			if( hd->homunculus.level >= battle_config.hom_max_level )
+				WBUFL(buf,63)=0;
+			break;
+		case HT_S:
+			if( hd->homunculus.level >= battle_config.hom_S_max_level )
+				WBUFL(buf,63)=0;
+			break;
+	}
 	WBUFW(buf,67)=hd->homunculus.skillpts;
 	WBUFW(buf,69)=status_get_range(&hd->bl);
 	clif_send(buf,packet_len(0x22e),&sd->bl,SELF);
@@ -11579,7 +11587,7 @@ void clif_parse_ReplyPartyInvite2(int fd,struct map_session_data *sd)
 /// 0100
 void clif_parse_LeaveParty(int fd, struct map_session_data *sd)
 {
-	if(map[sd->bl.m].flag.partylock) { //part locked.
+	if(map[sd->bl.m].flag.partylock) {// Party locked.
 		clif_displaymessage(fd, msg_txt(sd,227));
 		return;
 	}
@@ -11591,7 +11599,7 @@ void clif_parse_LeaveParty(int fd, struct map_session_data *sd)
 /// 0103 <account id>.L <char name>.24B
 void clif_parse_RemovePartyMember(int fd, struct map_session_data *sd)
 {
-	if(map[sd->bl.m].flag.partylock) { //party locked.
+	if(map[sd->bl.m].flag.partylock) {// Party locked.
 		clif_displaymessage(fd, msg_txt(sd,227));
 		return;
 	}

+ 12 - 0
src/map/homunculus.c

@@ -56,6 +56,18 @@ struct view_data* merc_get_hom_viewdata(int class_)
 	return NULL;
 }
 
+enum homun_type hom_class2type(int class_) {
+	int mid = hom_class2mapid(class_);
+	if(mid&(HOM_REG|HOM_EVO))
+		return HT_EVO;
+	else if(mid&(HOM_REG))
+		return HT_REG;
+	else if(mid&(HOM_S))
+		return HT_S;
+	else //invalid type
+		return -1;
+}
+
 int hom_class2mapid(int hom_class)
 {
 	switch(hom_class)

+ 6 - 1
src/map/homunculus.h

@@ -70,7 +70,6 @@ struct homun_skill_tree_entry {
 
 #define HOM_EVO 0x100 //256
 #define HOM_S 0x200 //512
-
 #define HOM_REG 0x1000 //4096
 
 enum {
@@ -91,6 +90,11 @@ enum {
 	MAPID_DIETER,
 	MAPID_ELANOR,
 };
+enum homun_type {
+	HT_REG	= 0x1,
+	HT_EVO	= 0x2,
+	HT_S	= 0x4,
+};
 
 #define homdb_checkid(id) (id >=  HM_CLASS_BASE && id <= HM_CLASS_MAX)
 
@@ -100,6 +104,7 @@ int do_init_merc(void);
 int merc_hom_recv_data(int account_id, struct s_homunculus *sh, int flag); //albator
 struct view_data* merc_get_hom_viewdata(int class_);
 int hom_class2mapid(int hom_class);
+enum homun_type hom_class2type(int class_);
 void merc_damage(struct homun_data *hd);
 int merc_hom_dead(struct homun_data *hd);
 void merc_hom_skillup(struct homun_data *hd,uint16 skill_id);

+ 2 - 0
src/map/map.c

@@ -3594,6 +3594,7 @@ void do_final(void)
 	do_final_elemental();
 	do_final_cashshop();
 	do_final_channel(); //should be called after final guild
+	do_final_vending();
 
 	map_db->destroy(map_db, map_db_final);
 
@@ -3900,6 +3901,7 @@ int do_init(int argc, char *argv[])
 	do_init_unit();
 	do_init_battleground();
 	do_init_duel();
+	do_init_vending();
 
 	npc_event_do_oninit();	// Init npcs (OnInit)
 

+ 2 - 2
src/map/mercenary.h

@@ -42,11 +42,11 @@ struct mercenary_data {
 	struct s_mercenary mercenary;
 	char blockskill[MAX_SKILL];
 
+	int masterteleport_timer;
 	struct map_session_data *master;
 	int contract_timer;
-	
+
 	unsigned devotion_flag : 1;
-	unsigned int masterteleport_timer;
 };
 
 bool merc_class(int class_);

+ 43 - 83
src/map/searchstore.c

@@ -12,8 +12,7 @@
 
 
 /// failure constants for clif functions
-enum e_searchstore_failure
-{
+enum e_searchstore_failure {
 	SSI_FAILED_NOTHING_SEARCH_ITEM         = 0,  // "No matching stores were found."
 	SSI_FAILED_OVER_MAXCOUNT               = 1,  // "There are too many results. Please enter more detailed search term."
 	SSI_FAILED_SEARCH_CNT                  = 2,  // "You cannot search anymore."
@@ -22,15 +21,13 @@ enum e_searchstore_failure
 };
 
 
-enum e_searchstore_searchtype
-{
+enum e_searchstore_searchtype {
 	SEARCHTYPE_VENDING      = 0,
 	SEARCHTYPE_BUYING_STORE = 1,
 };
 
 
-enum e_searchstore_effecttype
-{
+enum e_searchstore_effecttype {
 	EFFECTTYPE_NORMAL = 0,
 	EFFECTTYPE_CASH   = 1,
 	EFFECTTYPE_MAX
@@ -90,15 +87,12 @@ static int searchstore_getstoreid(struct map_session_data* sd, unsigned char typ
 }
 
 
-bool searchstore_open(struct map_session_data* sd, unsigned int uses, unsigned short effect)
-{
-	if( !battle_config.feature_search_stores || sd->searchstore.open )
-	{
+bool searchstore_open(struct map_session_data* sd, unsigned int uses, unsigned short effect) {
+	if( !battle_config.feature_search_stores || sd->searchstore.open ) {
 		return false;
 	}
 
-	if( !uses || effect >= EFFECTTYPE_MAX )
-	{// invalid input
+	if( !uses || effect >= EFFECTTYPE_MAX ) {// invalid input
 		return false;
 	}
 
@@ -116,63 +110,53 @@ void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned
 {
 	unsigned int i;
 	struct map_session_data* pl_sd;
-	struct s_mapiterator* iter;
+	struct DBIterator *iter;
 	struct s_search_store_search s;
 	searchstore_searchall_t store_searchall;
 	time_t querytime;
 
-	if( !battle_config.feature_search_stores )
-	{
+	if( !battle_config.feature_search_stores ) {
 		return;
 	}
 
-	if( !sd->searchstore.open )
-	{
+	if( !sd->searchstore.open ) {
 		return;
 	}
 
-	if( ( store_searchall = searchstore_getsearchallfunc(type) ) == NULL )
-	{
+	if( ( store_searchall = searchstore_getsearchallfunc(type) ) == NULL ) {
 		ShowError("searchstore_query: Unknown search type %u (account_id=%d).\n", (unsigned int)type, sd->bl.id);
 		return;
 	}
 
 	time(&querytime);
 
-	if( sd->searchstore.nextquerytime > querytime )
-	{
+	if( sd->searchstore.nextquerytime > querytime ) {
 		clif_search_store_info_failed(sd, SSI_FAILED_LIMIT_SEARCH_TIME);
 		return;
 	}
 
-	if( !sd->searchstore.uses )
-	{
+	if( !sd->searchstore.uses ) {
 		clif_search_store_info_failed(sd, SSI_FAILED_SEARCH_CNT);
 		return;
 	}
 
 	// validate lists
-	for( i = 0; i < item_count; i++ )
-	{
-		if( !itemdb_exists(itemlist[i]) )
-		{
+	for( i = 0; i < item_count; i++ ) {
+		if( !itemdb_exists(itemlist[i]) ) {
 			ShowWarning("searchstore_query: Client resolved item %hu is not known.\n", itemlist[i]);
 			clif_search_store_info_failed(sd, SSI_FAILED_NOTHING_SEARCH_ITEM);
 			return;
 		}
 	}
-	for( i = 0; i < card_count; i++ )
-	{
-		if( !itemdb_exists(cardlist[i]) )
-		{
+	for( i = 0; i < card_count; i++ ) {
+		if( !itemdb_exists(cardlist[i]) ) {
 			ShowWarning("searchstore_query: Client resolved card %hu is not known.\n", cardlist[i]);
 			clif_search_store_info_failed(sd, SSI_FAILED_NOTHING_SEARCH_ITEM);
 			return;
 		}
 	}
 
-	if( max_price < min_price )
-	{
+	if( max_price < min_price ) {
 		swap(min_price, max_price);
 	}
 
@@ -194,26 +178,23 @@ void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned
 	s.card_count = card_count;
 	s.min_price  = min_price;
 	s.max_price  = max_price;
-	iter         = mapit_geteachpc();
+	DBMap *vending_db = vending_getdb();
+	iter         = db_iterator(vending_db);
 
-	for( pl_sd = (struct map_session_data*)mapit_first(iter); mapit_exists(iter);  pl_sd = (struct map_session_data*)mapit_next(iter) )
-	{
-		if( sd == pl_sd )
-		{// skip own shop, if any
+	for( pl_sd = dbi_first(iter); dbi_exists(iter);  pl_sd = dbi_next(iter) ) {
+		if( sd == pl_sd ) {// skip own shop, if any
 			continue;
 		}
 
-		if( !store_searchall(pl_sd, &s) )
-		{// exceeded result size
+		if( !store_searchall(pl_sd, &s) ) {// exceeded result size
 			clif_search_store_info_failed(sd, SSI_FAILED_OVER_MAXCOUNT);
 			break;
 		}
 	}
 
-	mapit_free(iter);
+	dbi_destroy(iter);
 
-	if( sd->searchstore.count )
-	{
+	if( sd->searchstore.count ) {
 		// reclaim unused memory
 		sd->searchstore.items = (struct s_search_store_info_item*)aRealloc(sd->searchstore.items, sizeof(struct s_search_store_info_item)*sd->searchstore.count);
 
@@ -222,9 +203,7 @@ void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned
 
 		// one page displayed
 		sd->searchstore.pages++;
-	}
-	else
-	{
+	} else {
 		// cleanup
 		searchstore_clear(sd);
 
@@ -238,10 +217,8 @@ void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned
 
 
 /// checks whether or not more results are available for the client
-bool searchstore_querynext(struct map_session_data* sd)
-{
-	if( sd->searchstore.count && ( sd->searchstore.count-1 )/SEARCHSTORE_RESULTS_PER_PAGE < sd->searchstore.pages )
-	{
+bool searchstore_querynext(struct map_session_data* sd) {
+	if( sd->searchstore.count && ( sd->searchstore.count-1 )/SEARCHSTORE_RESULTS_PER_PAGE < sd->searchstore.pages ) {
 		return true;
 	}
 
@@ -249,8 +226,7 @@ bool searchstore_querynext(struct map_session_data* sd)
 }
 
 
-void searchstore_next(struct map_session_data* sd)
-{
+void searchstore_next(struct map_session_data* sd) {
 	if( !battle_config.feature_search_stores || !sd->searchstore.open || sd->searchstore.count <= sd->searchstore.pages*SEARCHSTORE_RESULTS_PER_PAGE )
 	{// nothing (more) to display
 		return;
@@ -264,12 +240,10 @@ void searchstore_next(struct map_session_data* sd)
 }
 
 
-void searchstore_clear(struct map_session_data* sd)
-{
+void searchstore_clear(struct map_session_data* sd) {
 	searchstore_clearremote(sd);
 
-	if( sd->searchstore.items )
-	{// release results
+	if( sd->searchstore.items ) {// release results
 		aFree(sd->searchstore.items);
 		sd->searchstore.items = NULL;
 	}
@@ -279,10 +253,8 @@ void searchstore_clear(struct map_session_data* sd)
 }
 
 
-void searchstore_close(struct map_session_data* sd)
-{
-	if( sd->searchstore.open )
-	{
+void searchstore_close(struct map_session_data* sd) {
+	if( sd->searchstore.open ) {
 		searchstore_clear(sd);
 
 		sd->searchstore.uses = 0;
@@ -291,29 +263,25 @@ void searchstore_close(struct map_session_data* sd)
 }
 
 
-void searchstore_click(struct map_session_data* sd, int account_id, int store_id, unsigned short nameid)
-{
+void searchstore_click(struct map_session_data* sd, int account_id, int store_id, unsigned short nameid) {
 	unsigned int i;
 	struct map_session_data* pl_sd;
 	searchstore_search_t store_search;
 
-	if( !battle_config.feature_search_stores || !sd->searchstore.open || !sd->searchstore.count )
-	{
+	if( !battle_config.feature_search_stores || !sd->searchstore.open || !sd->searchstore.count ) {
 		return;
 	}
 
 	searchstore_clearremote(sd);
 
 	ARR_FIND( 0, sd->searchstore.count, i,  sd->searchstore.items[i].store_id == store_id && sd->searchstore.items[i].account_id == account_id && sd->searchstore.items[i].nameid == nameid );
-	if( i == sd->searchstore.count )
-	{// no such result, crafted
+	if( i == sd->searchstore.count ) {// no such result, crafted
 		ShowWarning("searchstore_click: Received request with item %hu of account %d, which is not part of current result set (account_id=%d, char_id=%d).\n", nameid, account_id, sd->bl.id, sd->status.char_id);
 		clif_search_store_info_failed(sd, SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE);
 		return;
 	}
 
-	if( ( pl_sd = map_id2sd(account_id) ) == NULL )
-	{// no longer online
+	if( ( pl_sd = map_id2sd(account_id) ) == NULL ) {// no longer online
 		clif_search_store_info_failed(sd, SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE);
 		return;
 	}
@@ -326,23 +294,18 @@ void searchstore_click(struct map_session_data* sd, int account_id, int store_id
 
 	store_search = searchstore_getsearchfunc(sd->searchstore.type);
 
-	if( !store_search(pl_sd, nameid) )
-	{// item no longer being sold/bought
+	if( !store_search(pl_sd, nameid) ) {// item no longer being sold/bought
 		clif_search_store_info_failed(sd, SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE);
 		return;
 	}
 
-	switch( sd->searchstore.effect )
-	{
+	switch( sd->searchstore.effect ) {
 		case EFFECTTYPE_NORMAL:
 			// display coords
 
-			if( sd->bl.m != pl_sd->bl.m )
-			{// not on same map, wipe previous marker
+			if( sd->bl.m != pl_sd->bl.m ) {// not on same map, wipe previous marker
 				clif_search_store_info_click_ack(sd, -1, -1);
-			}
-			else
-			{
+			} else {
 				clif_search_store_info_click_ack(sd, pl_sd->bl.x, pl_sd->bl.y);
 			}
 
@@ -368,15 +331,13 @@ void searchstore_click(struct map_session_data* sd, int account_id, int store_id
 
 
 /// checks whether or not sd has opened account_id's shop remotely
-bool searchstore_queryremote(struct map_session_data* sd, int account_id)
-{
+bool searchstore_queryremote(struct map_session_data* sd, int account_id) {
 	return (bool)( sd->searchstore.open && sd->searchstore.count && sd->searchstore.remote_id == account_id );
 }
 
 
 /// removes range-check bypassing for remotely opened stores
-void searchstore_clearremote(struct map_session_data* sd)
-{
+void searchstore_clearremote(struct map_session_data* sd) {
 	sd->searchstore.remote_id = 0;
 }
 
@@ -386,8 +347,7 @@ bool searchstore_result(struct map_session_data* sd, int store_id, int account_i
 {
 	struct s_search_store_info_item* ssitem;
 
-	if( sd->searchstore.count >= (unsigned int)battle_config.searchstore_maxresults )
-	{// no more
+	if( sd->searchstore.count >= (unsigned int)battle_config.searchstore_maxresults ) {// no more
 		return false;
 	}
 

+ 3 - 6
src/map/searchstore.h

@@ -7,8 +7,7 @@
 #define SEARCHSTORE_RESULTS_PER_PAGE 10
 
 /// information about the search being performed
-struct s_search_store_search
-{
+struct s_search_store_search {
 	struct map_session_data* search_sd;  // sd of the searching player
 	const unsigned short* itemlist;
 	const unsigned short* cardlist;
@@ -18,8 +17,7 @@ struct s_search_store_search
 	unsigned int max_price;
 };
 
-struct s_search_store_info_item
-{
+struct s_search_store_info_item {
 	int store_id;
 	int account_id;
 	char store_name[MESSAGE_SIZE];
@@ -30,8 +28,7 @@ struct s_search_store_info_item
 	unsigned char refine;
 };
 
-struct s_search_store_info
-{
+struct s_search_store_info {
 	unsigned int count;
 	struct s_search_store_info_item* items;
 	unsigned int pages;  // amount of pages already sent to client

+ 3 - 2
src/map/skill.c

@@ -5194,9 +5194,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 		break;
 	case SA_INSTANTDEATH:
 		clif_skill_nodamage(src,bl,skill_id,skill_lv,1);
-		status_set_hp(bl,1,0);
+		status_kill(src);
 		break;
 	case SA_QUESTION:
+		clif_emotion(src,E_WHAT);
 	case SA_GRAVITY:
 		clif_skill_nodamage(src,bl,skill_id,skill_lv,1);
 		break;
@@ -9601,7 +9602,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data)
 
 	//Skill failed.
 	if (ud->skill_id == MO_EXTREMITYFIST && sd && !(sc && sc->data[SC_FOGWALL]))
-	{	//When Asura fails... (except when it fails from Fog of Wall)
+	{	//When Asura fails... (except when it fails from Wall of Fog)
 		//Consume SP/spheres
 		skill_consume_requirement(sd,ud->skill_id, ud->skill_lv,1);
 		status_set_sp(src, 0, 0);

+ 16 - 13
src/map/status.c

@@ -163,9 +163,9 @@ static void set_sc(uint16 skill_id, sc_type sc, int icon, unsigned int flag)
 	}
 
 	if( StatusSkillChangeTable[sc] == 0 )
-  		StatusSkillChangeTable[sc] = skill_id;
+		StatusSkillChangeTable[sc] = skill_id;
 	if( StatusIconChangeTable[sc] == SI_BLANK )
-  		StatusIconChangeTable[sc] = icon;
+		StatusIconChangeTable[sc] = icon;
 	StatusChangeFlagTable[sc] |= flag;
 
 	if( SkillStatusChangeTable[idx] == SC_NONE )
@@ -954,6 +954,7 @@ void initChangeTables(void) {
 	StatusChangeFlagTable[SC_SPCOST_RATE] |= SCB_ALL;
 	StatusChangeFlagTable[SC_WALKSPEED] |= SCB_SPEED;
 	StatusChangeFlagTable[SC_ITEMSCRIPT] |= SCB_ALL;
+	StatusChangeFlagTable[SC_SLOWDOWN] |= SCB_SPEED;
 	// Cash Items
 	StatusChangeFlagTable[SC_FOOD_STR_CASH] = SCB_STR;
 	StatusChangeFlagTable[SC_FOOD_AGI_CASH] = SCB_AGI;
@@ -2069,8 +2070,8 @@ int status_calc_mob_(struct mob_data* md, bool first)
 					status->max_hp = 10 * (100 * (ud->skill_lv + 2) + homblvl);
 					status->batk = 100 * (ud->skill_lv+5) / 2;
 					status->def = 10 * (100 * (ud->skill_lv+2) + homblvl);
-					//    status->aspd_rate = 10 * (2 * (20 - ud->skill_lv) - homblvl/10);
-					//    status->aspd_rate = max(100,status->aspd_rate);
+					//status->aspd_rate = 10 * (2 * (20 - ud->skill_lv) - homblvl/10);
+					//status->aspd_rate = max(100,status->aspd_rate);
 					break;
 				}
 			}
@@ -4376,7 +4377,7 @@ static unsigned short status_calc_vit(struct block_list *bl, struct status_chang
 	if(sc->data[SC_KYOUGAKU])
 		vit -= sc->data[SC_KYOUGAKU]->val2;
 
-	if(sc->data[SC_STRIPARMOR])
+	if(sc->data[SC_STRIPARMOR] && bl->type != BL_PC)
 		vit -= vit * sc->data[SC_STRIPARMOR]->val2/100;
 
 	return (unsigned short)cap_value(vit,0,USHRT_MAX);
@@ -4430,10 +4431,12 @@ static unsigned short status_calc_int(struct block_list *bl, struct status_chang
 	if(sc->data[SC_KYOUGAKU])
 		int_ -= sc->data[SC_KYOUGAKU]->val2;
 
-	if(sc->data[SC_STRIPHELM])
-		int_ -= int_ * sc->data[SC_STRIPHELM]->val2/100;
-	if(sc->data[SC__STRIPACCESSORY])
-		int_ -= int_ * sc->data[SC__STRIPACCESSORY]->val2 / 100;
+	if(bl->type != BL_PC){
+		if(sc->data[SC_STRIPHELM])
+			int_ -= int_ * sc->data[SC_STRIPHELM]->val2/100;
+		if(sc->data[SC__STRIPACCESSORY])
+			int_ -= int_ * sc->data[SC__STRIPACCESSORY]->val2 / 100;
+	}
 
 	return (unsigned short)cap_value(int_,0,USHRT_MAX);
 }
@@ -4488,7 +4491,7 @@ static unsigned short status_calc_dex(struct block_list *bl, struct status_chang
 	if(sc->data[SC_KYOUGAKU])
 		dex -= sc->data[SC_KYOUGAKU]->val2;
 
-	if(sc->data[SC__STRIPACCESSORY])
+	if(sc->data[SC__STRIPACCESSORY]  && bl->type != BL_PC)
 		dex -= dex * sc->data[SC__STRIPACCESSORY]->val2 / 100;
 
 	return (unsigned short)cap_value(dex,0,USHRT_MAX);
@@ -4534,7 +4537,7 @@ static unsigned short status_calc_luk(struct block_list *bl, struct status_chang
 	if(sc->data[SC_LAUDARAMUS])
 		luk += 4 + sc->data[SC_LAUDARAMUS]->val1;
 
-	if(sc->data[SC__STRIPACCESSORY])
+	if(sc->data[SC__STRIPACCESSORY] && bl->type != BL_PC)
 		luk -= luk * sc->data[SC__STRIPACCESSORY]->val2 / 100;
 	if(sc->data[SC_BANANA_BOMB])
 		luk -= luk * sc->data[SC_BANANA_BOMB]->val1 / 100;
@@ -4672,7 +4675,7 @@ static unsigned short status_calc_watk(struct block_list *bl, struct status_chan
 		watk += watk * sc->data[SC_FLEET]->val3/100;
 	if(sc->data[SC_CURSE])
 		watk -= watk * 25/100;
-	if(sc->data[SC_STRIPWEAPON])
+	if(sc->data[SC_STRIPWEAPON]  && bl->type != BL_PC)
 		watk -= watk * sc->data[SC_STRIPWEAPON]->val2/100;
 	if(sc->data[SC__ENERVATION])
 		watk -= watk * sc->data[SC__ENERVATION]->val2 / 100;
@@ -4978,7 +4981,7 @@ static defType status_calc_def(struct block_list *bl, struct status_change *sc,
 		def >>=1;
 	if(sc->data[SC_PROVOKE] && bl->type != BL_PC) // Provoke doesn't alter player defense->
 		def -= def * sc->data[SC_PROVOKE]->val4/100;
-	if(sc->data[SC_STRIPSHIELD])
+	if(sc->data[SC_STRIPSHIELD] && bl->type != BL_PC) //Player doesn't have def reduction only equip removed
 		def -= def * sc->data[SC_STRIPSHIELD]->val2/100;
 	if (sc->data[SC_FLING])
 		def -= def * (sc->data[SC_FLING]->val2)/100;

+ 2 - 4
src/map/unit.c

@@ -170,14 +170,13 @@ int unit_check_start_teleport_timer(struct block_list *sbl){
 	}
 	if(msd){ //if there is a master
 		int *msd_tid = unit_get_masterteleport_timer(sbl);
-		if(msd_tid == NULL) return 0;
 
 		if (!check_distance_bl(&msd->bl, sbl, MAX_MER_DISTANCE)) {
-			if(*msd_tid == INVALID_TIMER)
+			if(*msd_tid == INVALID_TIMER || *msd_tid == 0)
 				*msd_tid = add_timer(gettick()+3000,unit_teleport_timer,sbl->id,BL_MER);
 		}
 		else {
-			if(*msd_tid != INVALID_TIMER)
+			if(*msd_tid && *msd_tid != INVALID_TIMER)
 				delete_timer(*msd_tid,unit_teleport_timer);
 			*msd_tid = INVALID_TIMER; //cancel recall
 		}
@@ -253,7 +252,6 @@ static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data
 	ud->walktimer = INVALID_TIMER;
 
 	if(sd) {
-		struct block_list *sbl; //slave bl
 		if( sd->touching_id )
 			npc_touchnext_areanpc(sd,false);
 		if(map_getcell(bl->m,x,y,CELL_CHKNPC)) {

+ 42 - 55
src/map/vending.c

@@ -21,7 +21,11 @@
 #include <string.h>
 
 static int vending_nextid = 0;
+static DBMap *vending_db;
 
+DBMap * vending_getdb(){
+	return vending_db;
+}
 /// Returns an unique vending shop id.
 static int vending_getuid(void)
 {
@@ -35,10 +39,10 @@ void vending_closevending(struct map_session_data* sd)
 {
 	nullpo_retv(sd);
 
-	if( sd->state.vending )
-	{
+	if( sd->state.vending ) {
 		sd->state.vending = false;
 		clif_closevendingboard(&sd->bl, 0);
+		idb_remove(vending_db, sd->status.char_id);
 	}
 }
 
@@ -80,8 +84,7 @@ void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const ui
 	if( vsd == NULL || !vsd->state.vending || vsd->bl.id == sd->bl.id )
 		return; // invalid shop
 
-	if( vsd->vender_id != uid )
-	{// shop has changed
+	if( vsd->vender_id != uid ) { // shop has changed
 		clif_buyvending(sd, 0, 0, 6);  // store information was incorrect
 		return;
 	}
@@ -102,8 +105,7 @@ void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const ui
 	// some checks
 	z = 0.; // zeny counter
 	w = 0;  // weight counter
-	for( i = 0; i < count; i++ )
-	{
+	for( i = 0; i < count; i++ ) {
 		short amount = *(uint16*)(data + 4*i + 0);
 		short idx    = *(uint16*)(data + 4*i + 2);
 		idx -= 2;
@@ -134,8 +136,7 @@ void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const ui
 
 		}
 		w += itemdb_weight(vsd->status.cart[idx].nameid) * amount;
-		if( w + sd->weight > sd->max_weight )
-		{
+		if( w + sd->weight > sd->max_weight ) {
 			clif_buyvending(sd, idx, amount, 2); // you can not buy, because overweight
 			return;
 		}
@@ -173,8 +174,7 @@ void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const ui
 		z -= z * (battle_config.vending_tax/10000.);
 	pc_getzeny(vsd, (int)z, LOG_TYPE_VENDING, sd);
 
-	for( i = 0; i < count; i++ )
-	{
+	for( i = 0; i < count; i++ ) {
 		short amount = *(uint16*)(data + 4*i + 0);
 		short idx    = *(uint16*)(data + 4*i + 2);
 		idx -= 2;
@@ -186,8 +186,7 @@ void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const ui
 		clif_vendingreport(vsd, idx, amount);
 
 		//print buyer's name
-		if( battle_config.buyer_name )
-		{
+		if( battle_config.buyer_name ) {
 			char temp[256];
 			sprintf(temp, msg_txt(sd,265), sd->status.name);
 			clif_disp_onlyself(vsd,temp,strlen(temp));
@@ -195,13 +194,11 @@ void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const ui
 	}
 
 	// compact the vending list
-	for( i = 0, cursor = 0; i < vsd->vend_num; i++ )
-	{
+	for( i = 0, cursor = 0; i < vsd->vend_num; i++ ) {
 		if( vsd->vending[i].amount == 0 )
 			continue;
 
-		if( cursor != i ) // speedup
-		{
+		if( cursor != i ) { // speedup
 			vsd->vending[cursor].index = vsd->vending[i].index;
 			vsd->vending[cursor].amount = vsd->vending[i].amount;
 			vsd->vending[cursor].value = vsd->vending[i].value;
@@ -212,19 +209,16 @@ void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const ui
 	vsd->vend_num = cursor;
 
 	//Always save BOTH: buyer and customer
-	if( save_settings&2 )
-	{
+	if( save_settings&2 ) {
 		chrif_save(sd,0);
 		chrif_save(vsd,0);
 	}
 
 	//check for @AUTOTRADE users [durf]
-	if( vsd->state.autotrade )
-	{
+	if( vsd->state.autotrade ) {
 		//see if there is anything left in the shop
 		ARR_FIND( 0, vsd->vend_num, i, vsd->vending[i].amount > 0 );
-		if( i == vsd->vend_num )
-		{
+		if( i == vsd->vend_num ) {
 			//Close Vending (this was automatically done by the client, we have to do it manually for autovenders) [Skotlex]
 			vending_closevending(vsd);
 			map_quit(vsd);	//They have no reason to stay around anymore, do they?
@@ -246,8 +240,7 @@ void vending_openvending(struct map_session_data* sd, const char* message, const
 
 	vending_skill_lvl = pc_checkskill(sd, MC_VENDING);
 	// skill level and cart check
-	if( !vending_skill_lvl || !pc_iscarton(sd) )
-	{
+	if( !vending_skill_lvl || !pc_iscarton(sd) ) {
 		clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0);
 		return;
 	}
@@ -261,8 +254,7 @@ void vending_openvending(struct map_session_data* sd, const char* message, const
 
 	// filter out invalid items
 	i = 0;
-	for( j = 0; j < count; j++ )
-	{
+	for( j = 0; j < count; j++ ) {
 		short index        = *(uint16*)(data + 8*j + 0);
 		short amount       = *(uint16*)(data + 8*j + 2);
 		unsigned int value = *(uint32*)(data + 8*j + 4);
@@ -288,8 +280,7 @@ void vending_openvending(struct map_session_data* sd, const char* message, const
 	if( i != j )
 		clif_displaymessage (sd->fd, msg_txt(sd,266)); //"Some of your items cannot be vended and were removed from the shop."
 
-	if( i == 0 )
-	{	// no valid item found
+	if( i == 0 ) { // no valid item found
 		clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0); // custom reply packet
 		return;
 	}
@@ -301,22 +292,21 @@ void vending_openvending(struct map_session_data* sd, const char* message, const
 
 	clif_openvending(sd,sd->bl.id,sd->vending);
 	clif_showvendingboard(&sd->bl,message,0);
+
+	idb_put(vending_db, sd->vender_id, sd);
 }
 
 
 /// Checks if an item is being sold in given player's vending.
-bool vending_search(struct map_session_data* sd, unsigned short nameid)
-{
+bool vending_search(struct map_session_data* sd, unsigned short nameid) {
 	int i;
 
-	if( !sd->state.vending )
-	{// not vending
+	if( !sd->state.vending ) { // not vending
 		return false;
 	}
 
 	ARR_FIND( 0, sd->vend_num, i, sd->status.cart[sd->vending[i].index].nameid == (short)nameid );
-	if( i == sd->vend_num )
-	{// not found
+	if( i == sd->vend_num ) { // not found
 		return false;
 	}
 
@@ -326,46 +316,36 @@ bool vending_search(struct map_session_data* sd, unsigned short nameid)
 
 /// Searches for all items in a vending, that match given ids, price and possible cards.
 /// @return Whether or not the search should be continued.
-bool vending_searchall(struct map_session_data* sd, const struct s_search_store_search* s)
-{
+bool vending_searchall(struct map_session_data* sd, const struct s_search_store_search* s) {
 	int i, c, slot;
 	unsigned int idx, cidx;
 	struct item* it;
 
-	if( !sd->state.vending )
-	{// not vending
+	if( !sd->state.vending ) // not vending
 		return true;
-	}
 
-	for( idx = 0; idx < s->item_count; idx++ )
-	{
+	for( idx = 0; idx < s->item_count; idx++ ) {
 		ARR_FIND( 0, sd->vend_num, i, sd->status.cart[sd->vending[i].index].nameid == (short)s->itemlist[idx] );
-		if( i == sd->vend_num )
-		{// not found
+		if( i == sd->vend_num ) {// not found
 			continue;
 		}
 		it = &sd->status.cart[sd->vending[i].index];
 
-		if( s->min_price && s->min_price > sd->vending[i].value )
-		{// too low price
+		if( s->min_price && s->min_price > sd->vending[i].value ) {// too low price
 			continue;
 		}
 
-		if( s->max_price && s->max_price < sd->vending[i].value )
-		{// too high price
+		if( s->max_price && s->max_price < sd->vending[i].value ) {// too high price
 			continue;
 		}
 
-		if( s->card_count )
-		{// check cards
-			if( itemdb_isspecial(it->card[0]) )
-			{// something, that is not a carded
+		if( s->card_count ) {// check cards
+			if( itemdb_isspecial(it->card[0]) ) {// something, that is not a carded
 				continue;
 			}
 			slot = itemdb_slot(it->nameid);
 
-			for( c = 0; c < slot && it->card[c]; c ++ )
-			{
+			for( c = 0; c < slot && it->card[c]; c ++ ) {
 				ARR_FIND( 0, s->card_count, cidx, s->cardlist[cidx] == it->card[c] );
 				if( cidx != s->card_count )
 				{// found
@@ -373,8 +353,7 @@ bool vending_searchall(struct map_session_data* sd, const struct s_search_store_
 				}
 			}
 
-			if( c == slot || !it->card[c] )
-			{// no card match
+			if( c == slot || !it->card[c] ) {// no card match
 				continue;
 			}
 		}
@@ -387,3 +366,11 @@ bool vending_searchall(struct map_session_data* sd, const struct s_search_store_
 
 	return true;
 }
+void do_final_vending(void) {
+	db_destroy(vending_db);
+}
+
+void do_init_vending(void) {
+	vending_db = idb_alloc(DB_OPT_BASE);
+	vending_nextid = 0;
+}

+ 4 - 0
src/map/vending.h

@@ -15,6 +15,10 @@ struct s_vending {
 	unsigned int value; //at wich price
 };
 
+DBMap * vending_getdb();
+void do_final_vending(void);
+void do_init_vending(void);
+
 void vending_closevending(struct map_session_data* sd);
 void vending_openvending(struct map_session_data* sd, const char* message, const uint8* data, int count);
 void vending_vendinglistreq(struct map_session_data* sd, int id);