diff options
-rw-r--r-- | .travis.yml | 16 | ||||
-rw-r--r-- | Hercules-12.sln | 7 | ||||
-rw-r--r-- | README.md | 3 | ||||
-rw-r--r-- | db/const.txt | 4 | ||||
-rw-r--r-- | npc/custom/bgqueue/flavius.txt | 5 | ||||
-rw-r--r-- | npc/custom/breeder.txt | 28 | ||||
-rw-r--r-- | src/map/battle.c | 10 | ||||
-rw-r--r-- | src/map/battleground.c | 82 | ||||
-rw-r--r-- | src/map/battleground.h | 1 | ||||
-rw-r--r-- | src/map/clif.c | 31 | ||||
-rw-r--r-- | src/map/clif.h | 2 | ||||
-rw-r--r-- | src/map/intif.c | 2 | ||||
-rw-r--r-- | src/map/map.c | 2 | ||||
-rw-r--r-- | src/map/script.c | 89 | ||||
-rw-r--r-- | src/map/script.h | 3 | ||||
-rw-r--r-- | src/map/skill.c | 10 | ||||
-rw-r--r-- | vcproj-12/plugin-sample.vcxproj | 120 |
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 @@ -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 |