summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml16
-rw-r--r--Hercules-12.sln7
-rw-r--r--README.md3
-rw-r--r--db/const.txt4
-rw-r--r--npc/custom/bgqueue/flavius.txt5
-rw-r--r--npc/custom/breeder.txt28
-rw-r--r--src/map/battle.c10
-rw-r--r--src/map/battleground.c82
-rw-r--r--src/map/battleground.h1
-rw-r--r--src/map/clif.c31
-rw-r--r--src/map/clif.h2
-rw-r--r--src/map/intif.c2
-rw-r--r--src/map/map.c2
-rw-r--r--src/map/script.c89
-rw-r--r--src/map/script.h3
-rw-r--r--src/map/skill.c10
-rw-r--r--vcproj-12/plugin-sample.vcxproj120
17 files changed, 305 insertions, 110 deletions
diff --git a/.travis.yml b/.travis.yml
index 9ae3460cb..7dd473fa6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,8 +2,22 @@ language: c
compiler:
- clang
- gcc
+
+before_script:
+ - uname -a
-script: uname -a && ./configure --enable-debug && make
+script:
+ - ./configure --enable-debug
+ - make -j3
+
+notifications:
+ email: false
+
+ irc:
+ channels:
+ - "irc.rizon.net#Hercules"
+ on_success: always
+ on_failure: always
branches:
only:
diff --git a/Hercules-12.sln b/Hercules-12.sln
index 4f271290f..d4e5229ab 100644
--- a/Hercules-12.sln
+++ b/Hercules-12.sln
@@ -1,4 +1,3 @@
-
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "char-server", "vcproj-12\char-server.vcxproj", "{D356871D-58E1-450B-967A-E4E9646175AF}"
@@ -9,6 +8,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "map-server", "vcproj-12\map
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mapcache", "vcproj-12\mapcache.vcxproj", "{D356871D-58E1-450B-967A-E7E9646175AF}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plugin-sample", "vcproj-12\plugin-sample.vcxproj", "{E64C56D3-CDFB-483B-900B-A62D216B6D2F}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -31,6 +32,10 @@ Global
{D356871D-58E1-450B-967A-E7E9646175AF}.Debug|Win32.Build.0 = Debug|Win32
{D356871D-58E1-450B-967A-E7E9646175AF}.Release|Win32.ActiveCfg = Release|Win32
{D356871D-58E1-450B-967A-E7E9646175AF}.Release|Win32.Build.0 = Release|Win32
+ {E64C56D3-CDFB-483B-900B-A62D216B6D2F}.Debug|Win32.ActiveCfg = Debug|Win32
+ {E64C56D3-CDFB-483B-900B-A62D216B6D2F}.Debug|Win32.Build.0 = Debug|Win32
+ {E64C56D3-CDFB-483B-900B-A62D216B6D2F}.Release|Win32.ActiveCfg = Release|Win32
+ {E64C56D3-CDFB-483B-900B-A62D216B6D2F}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/README.md b/README.md
index 301c96d30..f79cc5d51 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,8 @@
Hercules
========
+
+Build Status: [![Build Status](https://travis-ci.org/HerculesWS/Hercules.png?branch=master)](https://travis-ci.org/HerculesWS/Hercules)
+
Table of Contents
---------
* 1 What is Hercules?
diff --git a/db/const.txt b/db/const.txt
index 3b1aa6490..86b2b26bb 100644
--- a/db/const.txt
+++ b/db/const.txt
@@ -3161,6 +3161,6 @@ IT_AMMO 10
IT_DELAYCONSUME 11
IT_CASH 18
-HQO_OnDeath 1
-HQO_OnLogout 2
+HQO_OnLogout 1
+HQO_OnDeath 2
HQO_OnMapChange 3
diff --git a/npc/custom/bgqueue/flavius.txt b/npc/custom/bgqueue/flavius.txt
index 8f195f288..7e30bdd99 100644
--- a/npc/custom/bgqueue/flavius.txt
+++ b/npc/custom/bgqueue/flavius.txt
@@ -26,6 +26,7 @@ OnInit:
//$@bg_queue_id is cleared after this event ends
OnPlayerListReady:
+
set $@FlaviusBG1_id1, bg_create_team("bat_b01",10,290);
set $@FlaviusBG1_id2, bg_create_team("bat_b01",390,10);
@@ -121,9 +122,9 @@ L_OnPlayerQuit:
OnMatchOver:
if( $@FlaviusBG1_id1 || $@FlaviusBG1_id2 ) {
- bg_match_over("Flavius");
queuedel($@Croix_QueueBG1);
queuedel($@Guill_QueueBG1);
+ bg_match_over("Flavius");
}
if( $@FlaviusBG1_id1 ) { bg_destroy $@FlaviusBG1_id1; set $@FlaviusBG1_id1, 0; }
if( $@FlaviusBG1_id2 ) { bg_destroy $@FlaviusBG1_id2; set $@FlaviusBG1_id2, 0; }
@@ -186,11 +187,9 @@ OnMyMobDead:
donpcevent "time#bat_b01::OnEnable";
donpcevent "start#bat_b01::onReset";
}
- donpcevent "#bat_b01_timer::OnStop";
bg_updatescore "bat_b01",$@Guill_ScoreBG1,$@Croix_ScoreBG1;
bg_warp $@FlaviusBG1_id1,"bat_b01",10,290;
bg_warp $@FlaviusBG1_id2,"bat_b01",390,10;
- donpcevent "#bat_b01_timer::OnEnable";
}
end;
}
diff --git a/npc/custom/breeder.txt b/npc/custom/breeder.txt
index 2bb3c6274..fc4ebbafa 100644
--- a/npc/custom/breeder.txt
+++ b/npc/custom/breeder.txt
@@ -3,35 +3,47 @@
//===== By: ==================================================
//= Euphy
//===== Current Version: =====================================
-//= 1.1
+//= 1.2
//===== Description: =========================================
//= One-click automatic mount rentals.
//= Replaced 'close' with 'end' [Streusel]
+//= Fixed 'close' issues. [Joseph]
//============================================================
prontera,124,201,1 script Universal Rental NPC 726,{
if (ismounting()) {
message strcharinfo(0),"You must first remove your mount.";
- end; }
+ end;
+ }
else if ((eaclass()&EAJ_THIRDMASK==EAJ_RANGER) && !countitem(6124)) {
if (!checkfalcon() && getskilllv("HT_FALCON") && !checkoption(Option_Wug) && !checkoption(Option_Wugrider)) {
if(select(" ~ Falcon: ~ Warg")==1) setfalcon;
- else getitem 6124,1; }
- else getitem 6124,1; }
+ else getitem 6124,1;
+ specialeffect2 EF_TEIHIT3;
+ close;
+ }
+ else getitem 6124,1;
+ }
else if ((eaclass()&EAJ_THIRDMASK==EAJ_MECHANIC) && !checkcart() && getskilllv("MC_PUSHCART")) {
if (!checkmadogear() && getskilllv("NC_MADOLICENCE")) {
if(select(" ~ Cart: ~ Mado")==1) setcart;
- else setmadogear; }
- else setcart; }
+ else setmadogear;
+ specialeffect2 EF_TEIHIT3;
+ close;
+ }
+ else setcart;
+ }
else if (!checkcart() && getskilllv("MC_PUSHCART")) setcart;
else if (!checkfalcon() && getskilllv("HT_FALCON") && !checkoption(Option_Wug) && !checkoption(Option_Wugrider)) setfalcon;
else if (!checkriding() && getskilllv("KN_RIDING")) {
if (eaclass()&EAJ_THIRDMASK==EAJ_RUNE_KNIGHT) setdragon;
- else setriding; }
+ else setriding;
+ }
else if (!checkmadogear() && getskilllv("NC_MADOLICENCE")) setmadogear;
else {
message strcharinfo(0),"You do not meet requirements to rent.";
- end; }
+ end;
+ }
specialeffect2 EF_TEIHIT3;
end;
}
diff --git a/src/map/battle.c b/src/map/battle.c
index dbd3bf8e4..f72bdce06 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -5176,14 +5176,20 @@ int battle_calc_return_damage(struct block_list* bl, struct block_list *src, int
int rdamage = 0, damage = *dmg, trdamage = 0;
struct map_session_data* sd;
struct status_change* sc;
+#ifdef RENEWAL
int max_reflect_damage;
+ max_reflect_damage = max(status_get_max_hp(bl), status_get_max_hp(bl) * iStatus->get_lv(bl) / 100);
+#endif
sd = BL_CAST(BL_PC, bl);
sc = iStatus->get_sc(bl);
- max_reflect_damage = max(status_get_max_hp(bl), status_get_max_hp(bl) * iStatus->get_lv(bl) / 100);
+#ifdef RENEWAL
#define NORMALIZE_RDAMAGE(d){ trdamage += rdamage = max(1, min(max_reflect_damage, d)); }
-
+#else
+#define NORMALIZE_RDAMAGE(d){ trdamage += rdamage = max(1, d); }
+#endif
+
if( sc && sc->data[SC_CRESCENTELBOW] && !is_boss(src) && rnd()%100 < sc->data[SC_CRESCENTELBOW]->val2 ){
//ATK [{(Target HP / 100) x Skill Level} x Caster Base Level / 125] % + [Received damage x {1 + (Skill Level x 0.2)}]
int ratio = (status_get_hp(src) / 100) * sc->data[SC_CRESCENTELBOW]->val1 * iStatus->get_lv(bl) / 125;
diff --git a/src/map/battleground.c b/src/map/battleground.c
index 198ad6bad..3b2e0b1ce 100644
--- a/src/map/battleground.c
+++ b/src/map/battleground.c
@@ -93,6 +93,15 @@ int bg_team_join(int bg_id, struct map_session_data *sd)
bg->members[i].sd = sd;
bg->members[i].x = sd->bl.x;
bg->members[i].y = sd->bl.y;
+ /* populate 'where i came from' */
+ if(map[sd->bl.m].flag.nosave || map[sd->bl.m].instance_id >= 0){
+ struct map_data *m=&map[sd->bl.m];
+ if(m->save.map)
+ memcpy(&bg->members[i].source,&m->save,sizeof(struct point));
+ else
+ memcpy(&bg->members[i].source,&sd->status.save_point,sizeof(struct point));
+ } else
+ memcpy(&bg->members[i].source,&sd->status.last_point,sizeof(struct point));
bg->count++;
guild->send_dot_remove(sd);
@@ -115,7 +124,6 @@ int bg_team_leave(struct map_session_data *sd, int flag)
if( sd == NULL || !sd->bg_id )
return 0;
-
bg_send_dot_remove(sd);
bg_id = sd->bg_id;
sd->bg_id = 0;
@@ -124,21 +132,28 @@ int bg_team_leave(struct map_session_data *sd, int flag)
return 0;
ARR_FIND(0, MAX_BG_MEMBERS, i, bg_data->members[i].sd == sd);
- if( i < MAX_BG_MEMBERS ) // Removes member from BG
+ if( i < MAX_BG_MEMBERS ) { // Removes member from BG
+ if( sd->bg_queue.arena ) {
+ bg->queue_pc_cleanup(sd);
+ pc->setpos(sd,bg_data->members[i].source.map, bg_data->members[i].source.x, bg_data->members[i].source.y, CLR_OUTSIGHT);
+ }
memset(&bg_data->members[i], 0, sizeof(bg_data->members[0]));
- bg_data->count--;
+ }
- if( flag )
- sprintf(output, "Server : %s has quit the game...", sd->status.name);
- else
- sprintf(output, "Server : %s is leaving the battlefield...", sd->status.name);
- clif->bg_message(bg_data, 0, "Server", output, strlen(output) + 1);
+ if( --bg_data->count != 0 ) {
+ if( flag )
+ sprintf(output, "Server : %s has quit the game...", sd->status.name);
+ else
+ sprintf(output, "Server : %s is leaving the battlefield...", sd->status.name);
+ clif->bg_message(bg_data, 0, "Server", output, strlen(output) + 1);
+ }
if( bg_data->logout_event[0] && flag )
npc_event(sd, bg_data->logout_event, 0);
-
- if( sd->bg_queue.arena )
+
+ if( sd->bg_queue.arena ) {
bg->queue_pc_cleanup(sd);
+ }
return bg_data->count;
}
@@ -415,10 +430,13 @@ struct bg_arena *bg_name2arena (char *name) {
int bg_id2pos ( int queue_id, int account_id ) {
struct hQueue *queue = script->queue(queue_id);
if( queue ) {
- int i;
- for(i = 0; i < queue->items; i++ ) {
- if( queue->item[i] == account_id ) {
- return i;
+ int i, pos = 1;
+ for(i = 0; i < queue->size; i++ ) {
+ if( queue->item[i] > 0 ) {
+ if( queue->item[i] == account_id ) {
+ return pos;
+ }
+ pos++;
}
}
}
@@ -436,14 +454,14 @@ void bg_queue_ready_ack (struct bg_arena *arena, struct map_session_data *sd, bo
int i, count = 0;
sd->bg_queue.ready = 1;
- for( i = 0; i < queue->items; i++ ) {
- if( ( sd = iMap->id2sd(queue->item[i]) ) ) {
+ for( i = 0; i < queue->size; i++ ) {
+ if( queue->item[i] > 0 && ( sd = iMap->id2sd(queue->item[i]) ) ) {
if( sd->bg_queue.ready == 1 )
count++;
}
}
/* check if all are ready then cancell timer, and start game */
- if( count == i ) {
+ if( count == queue->items ) {
iTimer->delete_timer(arena->begin_timer,bg->begin_timer);
arena->begin_timer = INVALID_TIMER;
bg->begin(arena);
@@ -454,7 +472,10 @@ void bg_queue_ready_ack (struct bg_arena *arena, struct map_session_data *sd, bo
}
void bg_queue_player_cleanup(struct map_session_data *sd) {
if ( sd->bg_queue.client_has_bg_data ) {
- clif->bgqueue_notice_delete(sd,BGQND_CLOSEWINDOW, sd->bg_queue.arena ? sd->bg_queue.arena->id : 0);
+ if( sd->bg_queue.arena )
+ clif->bgqueue_notice_delete(sd,BGQND_CLOSEWINDOW,sd->bg_queue.arena->name);
+ else
+ clif->bgqueue_notice_delete(sd,BGQND_FAIL_NOT_QUEUING,bg->arena[0]->name);
}
if( sd->bg_queue.arena )
script->queue_remove(sd->bg_queue.arena->queue_id,sd->status.account_id);
@@ -469,12 +490,16 @@ void bg_match_over(struct bg_arena *arena, bool canceled) {
if( !arena->ongoing )
return;
-
- for( i = 0; i < queue->items; i++ ) {
+ arena->ongoing = false;
+
+ for( i = 0; i < queue->size; i++ ) {
struct map_session_data * sd = NULL;
- if( ( sd = iMap->id2sd(queue->item[i]) ) ) {
- bg->queue_pc_cleanup(sd);
+ if( queue->item[i] > 0 && ( sd = iMap->id2sd(queue->item[i]) ) ) {
+ if( sd->bg_queue.arena ) {
+ bg_team_leave(sd, 0);
+ bg->queue_pc_cleanup(sd);
+ }
if( canceled )
clif->colormes(sd->fd,COLOR_RED,"BG Match Cancelled: not enough players");
else {
@@ -485,7 +510,6 @@ void bg_match_over(struct bg_arena *arena, bool canceled) {
arena->begin_timer = INVALID_TIMER;
arena->fillup_timer = INVALID_TIMER;
- arena->ongoing = false;
/* reset queue */
script->queue_clear(arena->queue_id);
}
@@ -493,10 +517,10 @@ void bg_begin(struct bg_arena *arena) {
struct hQueue *queue = &script->hq[arena->queue_id];
int i, count = 0;
- for( i = 0; i < queue->items; i++ ) {
+ for( i = 0; i < queue->size; i++ ) {
struct map_session_data * sd = NULL;
- if( ( sd = iMap->id2sd(queue->item[i]) ) ) {
+ if( queue->item[i] > 0 && ( sd = iMap->id2sd(queue->item[i]) ) ) {
if( sd->bg_queue.ready == 1 )
count++;
else
@@ -527,10 +551,10 @@ void bg_queue_pregame(struct bg_arena *arena) {
struct hQueue *queue = &script->hq[arena->queue_id];
int i;
- for( i = 0; i < queue->items; i++ ) {
+ for( i = 0; i < queue->size; i++ ) {
struct map_session_data * sd = NULL;
- if( ( sd = iMap->id2sd(queue->item[i]) ) ) {
+ if( queue->item[i] > 0 && ( sd = iMap->id2sd(queue->item[i]) ) ) {
clif->bgqueue_battlebegins(sd,arena->id,SELF);
}
}
@@ -594,7 +618,7 @@ void bg_queue_add(struct map_session_data *sd, struct bg_arena *arena, enum bg_q
clif->bgqueue_ack(sd,BGQA_FAIL_PPL_OVERAMOUNT,arena->id);
return;
}
-
+
switch( type ) {
case BGQT_INDIVIDUAL:
sd->bg_queue.type = type;
@@ -630,7 +654,7 @@ void bg_queue_add(struct map_session_data *sd, struct bg_arena *arena, enum bg_q
}
break;
}
-
+
clif->bgqueue_ack(sd,BGQA_SUCCESS,arena->id);
bg->queue_check(arena);
diff --git a/src/map/battleground.h b/src/map/battleground.h
index b6d95b813..1566e92b8 100644
--- a/src/map/battleground.h
+++ b/src/map/battleground.h
@@ -29,6 +29,7 @@ struct battleground_member_data {
unsigned short x, y;
struct map_session_data *sd;
unsigned afk : 1;
+ struct point source;/* where did i come from before i join? */
};
struct battleground_data {
diff --git a/src/map/clif.c b/src/map/clif.c
index 5cdd543cb..3657d0e43 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -558,10 +558,10 @@ int clif_send(const void* buf, int len, struct block_list* bl, enum send_target
if( sd && sd->bg_queue.arena ) {
struct hQueue *queue = &script->hq[sd->bg_queue.arena->queue_id];
- for( i = 0; i < queue->items; i++ ) {
+ for( i = 0; i < queue->size; i++ ) {
struct map_session_data * sd = NULL;
- if( ( sd = iMap->id2sd(queue->item[i]) ) ) {
+ if( queue->item[i] > 0 && ( sd = iMap->id2sd(queue->item[i]) ) ) {
WFIFOHEAD(sd->fd,len);
memcpy(WFIFOP(sd->fd,0), buf, len);
WFIFOSET(sd->fd,len);
@@ -15894,7 +15894,7 @@ void clif_bg_message(struct battleground_data *bg, int src_id, const char *name,
{
struct map_session_data *sd;
unsigned char *buf;
- if( (sd = bg_getavailablesd(bg)) == NULL )
+ if( !bg->count || (sd = bg_getavailablesd(bg)) == NULL )
return;
buf = (unsigned char*)aMalloc((len + NAME_LENGTH + 8)*sizeof(unsigned char));
@@ -17426,12 +17426,12 @@ void clif_bgqueue_ack(struct map_session_data *sd, enum BATTLEGROUNDS_QUEUE_ACK
}
-void clif_bgqueue_notice_delete(struct map_session_data *sd, enum BATTLEGROUNDS_QUEUE_NOTICE_DELETED response, unsigned char arena_id) {
+void clif_bgqueue_notice_delete(struct map_session_data *sd, enum BATTLEGROUNDS_QUEUE_NOTICE_DELETED response, char *name) {
struct packet_bgqueue_notice_delete p;
p.PacketType = bgqueue_notice_deleteType;
p.type = response;
- safestrncpy(p.bg_name, bg->arena[arena_id]->name, sizeof(p.bg_name));
+ safestrncpy(p.bg_name, name, sizeof(p.bg_name));
clif->send(&p,sizeof(p), &sd->bl, SELF);
}
@@ -17474,33 +17474,34 @@ void clif_bgqueue_update_info(struct map_session_data *sd, unsigned char arena_i
}
void clif_parse_bgqueue_checkstate(int fd, struct map_session_data *sd) {
- //struct packet_bgqueue_checkstate *p = P2PTR(fd, bgqueue_checkstateType); /* TODO: bgqueue_notice_delete should use this p->bg_name */
- if( !bg->queue_on ) return; /* temp, until feature is complete */
+ struct packet_bgqueue_checkstate *p = P2PTR(fd);
+
if ( sd->bg_queue.arena && sd->bg_queue.type ) {
clif->bgqueue_update_info(sd,sd->bg_queue.arena->id,bg->id2pos(sd->bg_queue.arena->queue_id,sd->status.account_id));
} else
- clif->bgqueue_notice_delete(sd, BGQND_FAIL_NOT_QUEUING,0);/* TODO: wrong response, should respond with p->bg_name not id 0 */
+ clif->bgqueue_notice_delete(sd, BGQND_FAIL_NOT_QUEUING,p->bg_name);
}
void clif_parse_bgqueue_revoke_req(int fd, struct map_session_data *sd) {
- //struct packet_bgqueue_revoke_req *p = P2PTR(fd, bgqueue_revokereqType);
- return;
- //bg->queue_leave(sd, p->bg_name);
+ struct packet_bgqueue_revoke_req *p = P2PTR(fd);
+
+ if( sd->bg_queue.arena )
+ bg->queue_pc_cleanup(sd);
+ else
+ clif->bgqueue_notice_delete(sd, BGQND_FAIL_NOT_QUEUING,p->bg_name);
}
void clif_parse_bgqueue_battlebegin_ack(int fd, struct map_session_data *sd) {
struct packet_bgqueue_battlebegin_ack *p = P2PTR(fd);
struct bg_arena *arena;
+
if( !bg->queue_on ) return; /* temp, until feature is complete */
+
if( ( arena = bg->name2arena(p->bg_name) ) ) {
bg->queue_ready_ack(arena,sd, ( p->result == 1 ) ? true : false);
} else {
clif->bgqueue_ack(sd,BGQA_FAIL_BGNAME_INVALID, 0);
}
- //if ( p->result == 1 )
- // bg->queue_pc_ready(sd);
- //else
- // bg->queue_leave(sd, p->bg_name);
}
void clif_bgqueue_joined(struct map_session_data *sd, int pos) {
diff --git a/src/map/clif.h b/src/map/clif.h
index 2cf193965..f931e41e7 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -906,7 +906,7 @@ struct clif_interface {
void (*elemental_updatestatus) (struct map_session_data *sd, int type);
/* bgqueue */
void (*bgqueue_ack) (struct map_session_data *sd, enum BATTLEGROUNDS_QUEUE_ACK response, unsigned char arena_id);
- void (*bgqueue_notice_delete) (struct map_session_data *sd, enum BATTLEGROUNDS_QUEUE_NOTICE_DELETED response, unsigned char arena_id);
+ void (*bgqueue_notice_delete) (struct map_session_data *sd, enum BATTLEGROUNDS_QUEUE_NOTICE_DELETED response, char *name);
void (*bgqueue_update_info) (struct map_session_data *sd, unsigned char arena_id, int position);
void (*bgqueue_joined) (struct map_session_data *sd, int pos);
void (*bgqueue_pcleft) (struct map_session_data *sd);
diff --git a/src/map/intif.c b/src/map/intif.c
index a16b5cda3..6461dce8e 100644
--- a/src/map/intif.c
+++ b/src/map/intif.c
@@ -2269,6 +2269,8 @@ void intif_defaults(void) {
/* funcs */
intif->parse = intif_parse;
+
+ intif->create_pet = intif_create_pet;
intif->broadcast = intif_broadcast;
intif->broadcast2 = intif_broadcast2;
diff --git a/src/map/map.c b/src/map/map.c
index 55ec5effa..713577495 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -1538,7 +1538,7 @@ int map_quit(struct map_session_data *sd) {
if (sd->npc_id)
npc_event_dequeue(sd);
- if( sd->bg_id )
+ if( sd->bg_id && !sd->bg_queue.arena ) /* TODO: dump this chunk after bg_queue is fully enabled */
bg_team_leave(sd,1);
skill->cooldown_save(sd);
diff --git a/src/map/script.c b/src/map/script.c
index 336ab7b9f..3033a281b 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -17086,7 +17086,7 @@ BUILDIN(npcskill)
return true;
}
struct hQueue *script_hqueue_get(int idx) {
- if( idx < 0 || idx >= script->hqs || script->hq[idx].items == -1 )
+ if( idx < 0 || idx >= script->hqs || script->hq[idx].size == -1 )
return NULL;
return &script->hq[idx];
}
@@ -17095,7 +17095,7 @@ int script_hqueue_create(void) {
int i;
for(i = 0; i < script->hqs; i++) {
- if( script->hq[i].items == -1 ) {
+ if( script->hq[i].size == -1 ) {
break;
}
}
@@ -17107,6 +17107,7 @@ int script_hqueue_create(void) {
idx = i;
script->hq[ idx ].id = idx;
+ script->hq[ idx ].size = 0;
script->hq[ idx ].items = 0;
script->hq[ idx ].onDeath[0] = '\0';
script->hq[ idx ].onLogOut[0] = '\0';
@@ -17124,47 +17125,42 @@ BUILDIN(queue) {
BUILDIN(queuesize) {
int idx = script_getnum(st, 2);
- if( idx < 0 || idx >= script->hqs || script->hq[idx].items == -1 ) {
+ if( idx < 0 || idx >= script->hqs || script->hq[idx].size == -1 ) {
ShowWarning("buildin_queuesize: unknown queue id %d\n",idx);
script_pushint(st, 0);
} else {
- /* value of script->hq[].items isn't to be trusted for we dont reduce the size when members are removed to save on memory allocation */
- int i, count = 0;
- for( i = 0; i < script->hq[ idx ].items; i++ )
- if( script->hq[ idx ].item[i] != -1 )
- count++;
- script_pushint(st, count);
+ script_pushint(st, script->hq[ idx ].items);
}
return true;
}
bool script_hqueue_add(int idx, int var) {
- if( idx < 0 || idx >= script->hqs || script->hq[idx].items == -1 ) {
+ if( idx < 0 || idx >= script->hqs || script->hq[idx].size == -1 ) {
ShowWarning("script_hqueue_add: unknown queue id %d\n",idx);
return true;
} else {
struct map_session_data *sd;
int i;
- for(i = 0; i < script->hq[idx].items; i++) {
+ for(i = 0; i < script->hq[idx].size; i++) {
if( script->hq[idx].item[i] == var ) {
return true;
}
}
- if( i == script->hq[idx].items ) {
+ if( i == script->hq[idx].size ) {
- for(i = 0; i < script->hq[idx].items; i++) {
+ for(i = 0; i < script->hq[idx].size; i++) {
if( script->hq[idx].item[i] == 0 ) {
break;
}
}
- if( i == script->hq[idx].items )
- RECREATE(script->hq[idx].item, int, ++script->hq[idx].items);
+ if( i == script->hq[idx].size )
+ RECREATE(script->hq[idx].item, int, ++script->hq[idx].size);
script->hq[idx].item[i] = var;
-
+ script->hq[idx].items++;
if( var >= START_ACCOUNT_NUM && (sd = iMap->id2sd(var)) ) {
for(i = 0; i < sd->queues_count; i++) {
if( sd->queues[i] == -1 ) {
@@ -17193,21 +17189,23 @@ BUILDIN(queueadd) {
return true;
}
bool script_hqueue_remove(int idx, int var) {
- if( idx < 0 || idx >= script->hqs || script->hq[idx].items == -1 ) {
+ if( idx < 0 || idx >= script->hqs || script->hq[idx].size == -1 ) {
ShowWarning("script_hqueue_remove: unknown queue id %d (used with var %d)\n",idx,var);
return true;
} else {
int i;
- for(i = 0; i < script->hq[idx].items; i++) {
+ for(i = 0; i < script->hq[idx].size; i++) {
if( script->hq[idx].item[i] == var ) {
break;
}
}
- if( i != script->hq[idx].items ) {
+ if( i != script->hq[idx].size ) {
struct map_session_data *sd;
+
script->hq[idx].item[i] = -1;
+ script->hq[idx].items--;
if( var >= START_ACCOUNT_NUM && (sd = iMap->id2sd(var)) ) {
for(i = 0; i < sd->queues_count; i++) {
@@ -17243,7 +17241,7 @@ BUILDIN(queueopt) {
int idx = script_getnum(st, 2);
int var = script_getnum(st, 3);
- if( idx < 0 || idx >= script->hqs || script->hq[idx].items == -1 ) {
+ if( idx < 0 || idx >= script->hqs || script->hq[idx].size == -1 ) {
ShowWarning("buildin_queueopt: unknown queue id %d\n",idx);
script_pushint(st, 1);
} else if( var <= HQO_NONE || var >= HQO_MAX ) {
@@ -17279,14 +17277,14 @@ BUILDIN(queueopt) {
return true;
}
bool script_hqueue_del(int idx) {
- if( idx < 0 || idx >= script->hqs || script->hq[idx].items == -1 ) {
+ if( idx < 0 || idx >= script->hqs || script->hq[idx].size == -1 ) {
ShowWarning("script_queue_del: unknown queue id %d\n",idx);
return true;
} else {
struct map_session_data *sd;
int i;
- for(i = 0; i < script->hq[idx].items; i++) {
+ for(i = 0; i < script->hq[idx].size; i++) {
if( script->hq[idx].item[i] >= START_ACCOUNT_NUM && (sd = iMap->id2sd(script->hq[idx].item[i])) ) {
int j;
for(j = 0; j < sd->queues_count; j++) {
@@ -17298,9 +17296,11 @@ bool script_hqueue_del(int idx) {
if( j != sd->queues_count )
sd->queues[j] = -1;
}
+ script->hq[idx].item[i] = 0;
}
- script->hq[idx].items = -1;
+ script->hq[idx].size = -1;
+ script->hq[idx].items = 0;
}
return false;
}
@@ -17314,29 +17314,30 @@ BUILDIN(queuedel) {
return true;
}
void script_hqueue_clear(int idx) {
- if( idx < 0 || idx >= script->hqs || script->hq[idx].items == -1 ) {
+ if( idx < 0 || idx >= script->hqs || script->hq[idx].size == -1 ) {
ShowWarning("script_hqueue_clear: unknown queue id %d\n",idx);
return;
} else {
struct map_session_data *sd;
int i, j;
- for(i = 0; i < script->hq[idx].items; i++) {
- if( script->hq[idx].item[i] != -1 ) {
-
- if( script->hq[idx].item[i] >= START_ACCOUNT_NUM && (sd = iMap->id2sd(script->hq[idx].item[i])) ) {
- for(j = 0; j < sd->queues_count; j++) {
- if( sd->queues[j] == idx ) {
- break;
- }
+ for(i = 0; i < script->hq[idx].size; i++) {
+ if( script->hq[idx].item[i] > 0 ) {
+
+ if( script->hq[idx].item[i] >= START_ACCOUNT_NUM && (sd = iMap->id2sd(script->hq[idx].item[i])) ) {
+ for(j = 0; j < sd->queues_count; j++) {
+ if( sd->queues[j] == idx ) {
+ break;
}
-
- if( j != sd->queues_count )
- sd->queues[j] = -1;
}
- script->hq[idx].item[i] = -1;
+
+ if( j != sd->queues_count )
+ sd->queues[j] = -1;
}
+ script->hq[idx].item[i] = 0;
}
+ }
+ script->hq[idx].items = 0;
}
return;
}
@@ -17348,11 +17349,17 @@ BUILDIN(queueiterator) {
int idx = script->hqis;
int i;
- if( qid < 0 || qid >= script->hqs || script->hq[qid].items == -1 || !(queue = script->queue(qid)) ) {
+ if( qid < 0 || qid >= script->hqs || script->hq[qid].size == -1 || !(queue = script->queue(qid)) ) {
ShowWarning("queueiterator: invalid queue id %d\n",qid);
return true;
}
+ /* what if queue->size is 0? (iterating a empty queue?) */
+ if( queue->size <= 0 ) {
+ ShowWarning("queueiterator: attempting to iterate on on empty queue id %d!\n",qid);
+ return true;
+ }
+
for(i = 0; i < script->hqis; i++) {
if( script->hqi[i].items == -1 ) {
break;
@@ -17364,12 +17371,12 @@ BUILDIN(queueiterator) {
script->hqi[ idx ].item = NULL;
} else
idx = i;
+
+ RECREATE(script->hqi[ idx ].item, int, queue->size);
- RECREATE(script->hqi[ idx ].item, int, queue->items);
-
- memcpy(script->hqi[idx].item, queue->item, sizeof(int)*queue->items);
+ memcpy(script->hqi[idx].item, queue->item, sizeof(int)*queue->size);
- script->hqi[ idx ].items = queue->items;
+ script->hqi[ idx ].items = queue->size;
script->hqi[ idx ].pos = 0;
script_pushint(st,idx);
diff --git a/src/map/script.h b/src/map/script.h
index 82224a7af..774101eb3 100644
--- a/src/map/script.h
+++ b/src/map/script.h
@@ -142,7 +142,8 @@ struct script_stack {
struct hQueue {
int id;
int *item;
- int items;
+ int items;/* how many actual items are in the array */
+ int size;/* size of the *item array, not the current amount of items in it since it can have empty slots */
/* events */
char onLogOut[EVENT_NAME_LENGTH];
char onDeath[EVENT_NAME_LENGTH];
diff --git a/src/map/skill.c b/src/map/skill.c
index 995c20083..97f26cca6 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -16229,11 +16229,11 @@ int skill_produce_mix (struct map_session_data *sd, uint16 skill_id, int nameid,
**/
case GC_CREATENEWPOISON:
{
- const int min[] = {2, 2, 3, 3, 4, 4, 5, 5, 6, 6};
- const int max[] = {4, 5, 5, 6, 6, 7, 7, 8, 8, 9};
- uint16 lv = pc->checkskill(sd,GC_RESEARCHNEWPOISON);
- make_per = 3000 + 500 * lv ;
- qty = min[lv] + rand()%(max[lv] - min[lv]);
+ const int min[10] = {2, 2, 3, 3, 4, 4, 5, 5, 6, 6};
+ const int max[10] = {4, 5, 5, 6, 6, 7, 7, 8, 8, 9};
+ int lv = max(0, pc->checkskill(sd,GC_RESEARCHNEWPOISON) - 1);
+ qty = min[lv] + rnd()%(max[lv] - min[lv]);
+ make_per = 3000 + 500 * (lv+1);
}
break;
case GN_CHANGEMATERIAL:
diff --git a/vcproj-12/plugin-sample.vcxproj b/vcproj-12/plugin-sample.vcxproj
new file mode 100644
index 000000000..639cc9a66
--- /dev/null
+++ b/vcproj-12/plugin-sample.vcxproj
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{E64C56D3-CDFB-483B-900B-A62D216B6D2F}</ProjectGuid>
+ <RootNamespace>plugin-sample</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ <ProjectName>plugin-sample</ProjectName>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectName)\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectName)\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">plugin-sample</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">plugin-sample</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\src\common;..\3rdparty\msinttypes\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0417</Culture>
+ </ResourceCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName).dll</OutputFile>
+ <ModuleDefinitionFile>
+ </ModuleDefinitionFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>MaxSpeed</Optimization>
+ <AdditionalIncludeDirectories>..\src\common;..\3rdparty\msinttypes\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0417</Culture>
+ </ResourceCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName).dll</OutputFile>
+ <ModuleDefinitionFile>
+ </ModuleDefinitionFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\src\plugins\sample.c" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file