From 7c153416bc2b69bbb515c0a3e7a90bcb216d5e4a Mon Sep 17 00:00:00 2001 From: Lemon <47922762+Leemonn@users.noreply.github.com> Date: Wed, 20 Dec 2023 00:12:15 +0100 Subject: [PATCH] Improved randomness (part 1) (#7882) Faster and with no module bias Removed rnd_init, rnd_uint32 and rnd_uniform From now on we will only use rnd_value(min, max) for values in range [min, max] and rnd_chance(chance, base) for chances Fixes #7881 Fixes #7883 Fixes #7884 Fixes #7885 Co-authored-by: Lemongrass3110 --- src/common/random.cpp | 36 +----------------------------------- src/common/random.hpp | 26 ++++++++++++++++++++++---- src/common/utilities.hpp | 4 ++-- src/login/login.cpp | 6 ++---- src/login/login.hpp | 4 ++-- src/login/loginclif.cpp | 3 +-- src/map/atcommand.cpp | 8 ++++---- src/map/battleground.cpp | 2 +- src/map/clif.cpp | 4 ++-- src/map/elemental.cpp | 2 +- src/map/itemdb.cpp | 10 +++++----- src/map/map.cpp | 21 ++++++++------------- src/map/mercenary.cpp | 2 +- src/map/party.cpp | 2 +- src/map/path.cpp | 2 +- src/map/pet.cpp | 18 +++++++++--------- src/map/quest.cpp | 2 +- src/map/script.cpp | 26 +++++++++++++------------- src/map/skill.cpp | 8 ++++---- src/map/unit.cpp | 4 ++-- 20 files changed, 83 insertions(+), 107 deletions(-) diff --git a/src/common/random.cpp b/src/common/random.cpp index 6005341545..663af94bb7 100644 --- a/src/common/random.cpp +++ b/src/common/random.cpp @@ -3,43 +3,9 @@ #include "random.hpp" -#include - -std::mt19937 generator; -std::uniform_int_distribution int31_distribution; -std::uniform_int_distribution uint32_distribution; - -/// Initializes the random number generator -void rnd_init( void ){ - std::random_device device; - generator = std::mt19937( device() ); - int31_distribution = std::uniform_int_distribution( 0, SINT32_MAX ); - uint32_distribution = std::uniform_int_distribution( 0, UINT32_MAX ); -} +std::uniform_int_distribution int31_distribution = std::uniform_int_distribution(0, SINT32_MAX); /// Generates a random number in the interval [0, SINT32_MAX] int32 rnd( void ){ return int31_distribution( generator ); } - -/// Generates a random number in the interval [0, UINT32_MAX] -uint32 rnd_uint32( void ){ - return uint32_distribution( generator ); -} - -/// Generates a random number in the interval [0.0, 1.0) -/// NOTE: interval is open ended, so 1.0 is excluded -double rnd_uniform( void ){ - return rnd_uint32() * ( 1.0 / 4294967296.0 );// divided by 2^32 -} - -/// Generates a random number in the interval [min, max] -/// Returns min if range is invalid. -int32 rnd_value( int32 min, int32 max ){ - if( min >= max ){ - return min; - } - - return min + (int32)( rnd_uniform() * ( max - min + 1 ) ); -} - diff --git a/src/common/random.hpp b/src/common/random.hpp index c7fb7716bb..1ed4b91db7 100644 --- a/src/common/random.hpp +++ b/src/common/random.hpp @@ -4,15 +4,33 @@ #ifndef RANDOM_HPP #define RANDOM_HPP +#include +#include + #include "cbasetypes.hpp" -void rnd_init(void); +inline std::random_device device; +inline std::mt19937 generator = std::mt19937(device()); int32 rnd(void);// [0, SINT32_MAX] -int32 rnd_value(int32 min, int32 max);// [min, max] -template bool rnd_chance( T chance, T base ){ - return rnd_value( 0, base ) < chance; +/* + * Generates a random number in the interval [min, max] + * @return random number + */ +template +typename std::enable_if::value, T>::type rnd_value(T min, T max) { + std::uniform_int_distribution dist(min, max); + return dist(generator); +} + +/* + * Simulates a chance based on a given probability + * @return true if succeeded / false if it didn't + */ +template +typename std::enable_if::value, bool>::type rnd_chance(T chance, T base) { + return rnd_value(1, base) <= chance; } #endif /* RANDOM_HPP */ diff --git a/src/common/utilities.hpp b/src/common/utilities.hpp index 4837394ed8..f7a10dad9a 100644 --- a/src/common/utilities.hpp +++ b/src/common/utilities.hpp @@ -159,7 +159,7 @@ namespace rathena { template V& umap_random( std::unordered_map& map ){ auto it = map.begin(); - std::advance( it, rnd_value( 0, map.size() - 1 ) ); + std::advance( it, rnd_value( 0, map.size() - 1 ) ); return it->second; } @@ -172,7 +172,7 @@ namespace rathena { template K &vector_random(std::vector &vec) { auto it = vec.begin(); - std::advance(it, rnd_value(0, vec.size() - 1)); + std::advance( it, rnd_value( 0, vec.size() - 1 ) ); return *it; } diff --git a/src/login/login.cpp b/src/login/login.cpp index a5b5e28eaa..5862524ac2 100644 --- a/src/login/login.cpp +++ b/src/login/login.cpp @@ -403,8 +403,8 @@ int login_mmo_auth(struct login_session_data* sd, bool isServer) { // update session data sd->account_id = acc.account_id; - sd->login_id1 = rnd() + 1; - sd->login_id2 = rnd() + 1; + sd->login_id1 = rnd_value(1u, UINT32_MAX); + sd->login_id2 = rnd_value(1u, UINT32_MAX); safestrncpy(sd->lastlogin, acc.lastlogin, sizeof(sd->lastlogin)); sd->sex = acc.sex; sd->group_id = acc.group_id; @@ -846,8 +846,6 @@ bool LoginServer::initialize( int argc, char* argv[] ){ login_lan_config_read(login_config.lanconf_name); //end config - rnd_init(); - do_init_loginclif(); do_init_loginchrif(); diff --git a/src/login/login.hpp b/src/login/login.hpp index e2fe9170ee..0e99c18774 100644 --- a/src/login/login.hpp +++ b/src/login/login.hpp @@ -39,8 +39,8 @@ namespace rathena{ ///Struct of 1 client connected to login-serv struct login_session_data { uint32 account_id; ///also GID - long login_id1; - long login_id2; + uint32 login_id1; + uint32 login_id2; char sex; /// 'F','M','S' char userid[NAME_LENGTH]; /// account name diff --git a/src/login/loginclif.cpp b/src/login/loginclif.cpp index 330150e639..7201994da9 100644 --- a/src/login/loginclif.cpp +++ b/src/login/loginclif.cpp @@ -377,8 +377,7 @@ static int logclif_parse_reqauth(int fd, struct login_session_data *sd, int comm static int logclif_parse_reqkey(int fd, struct login_session_data *sd){ RFIFOSKIP(fd,2); { - memset(sd->md5key, '\0', sizeof(sd->md5key)); - sd->md5keylen = (uint16)(12 + rnd() % 4); + sd->md5keylen = sizeof( sd->md5key ); MD5_Salt(sd->md5keylen, sd->md5key); WFIFOHEAD(fd,4 + sd->md5keylen); diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp index 87f5deb895..bfe08a1867 100644 --- a/src/map/atcommand.cpp +++ b/src/map/atcommand.cpp @@ -7259,7 +7259,7 @@ ACMD_FUNC(pettalk) }; int i; ARR_FIND( 0, ARRAYLENGTH(emo), i, stricmp(message, emo[i]) == 0 ); - if( i == ET_DICE1 ) i = rnd()%6 + ET_DICE1; // randomize /dice + if( i == ET_DICE1 ) i = rnd_value(ET_DICE1, ET_DICE6); // randomize /dice if( i < ARRAYLENGTH(emo) ) { if (sd->emotionlasttime + 1 >= time(NULL)) { // not more than 1 per second @@ -8017,7 +8017,7 @@ ACMD_FUNC(hommutate) } if (!message || !*message) { - homun_id = 6048 + (rnd() % 4); + homun_id = rnd_value(MER_EIRA, MER_ELEANOR); } else { homun_id = atoi(message); } @@ -9133,8 +9133,8 @@ ACMD_FUNC(clone) } do { - x = sd->bl.x + (rnd() % 10 - 5); - y = sd->bl.y + (rnd() % 10 - 5); + x = sd->bl.x + rnd_value(-5, 5); + y = sd->bl.y + rnd_value(-5, 5); } while (map_getcell(sd->bl.m,x,y,CELL_CHKNOPASS) && i++ < 10); if (i >= 10) { diff --git a/src/map/battleground.cpp b/src/map/battleground.cpp index 6dda37f8ba..2bb37d6dbf 100644 --- a/src/map/battleground.cpp +++ b/src/map/battleground.cpp @@ -1172,7 +1172,7 @@ void bg_queue_join_multi(const char *name, map_session_data *sd, std::vector *team = r ? &queue->teamb_members : &queue->teama_members; if (queue->state == QUEUE_STATE_ACTIVE) { diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 47b2c1a896..998212a9cd 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -23561,11 +23561,11 @@ void clif_parse_laphine_upgrade( int fd, map_session_data* sd ){ item->refine = rnd_value( upgrade->resultRefineMinimum, upgrade->resultRefineMaximum ); }else{ // Otherwise it can only be upgraded until the maximum, but not downgraded - item->refine = rnd_value( item->refine, upgrade->resultRefineMaximum ); + item->refine = rnd_value( item->refine, upgrade->resultRefineMaximum ); } }else if( upgrade->resultRefineMinimum > 0 ){ // No maximum has been specified, so it can be anything between minimum and MAX_REFINE - item->refine = rnd_value( upgrade->resultRefineMinimum, MAX_REFINE ); + item->refine = rnd_value( upgrade->resultRefineMinimum, MAX_REFINE ); } // Log retrieving the item again -> with the new options diff --git a/src/map/elemental.cpp b/src/map/elemental.cpp index 93853c9934..19ea23072e 100644 --- a/src/map/elemental.cpp +++ b/src/map/elemental.cpp @@ -622,7 +622,7 @@ static int elemental_ai_sub_timer(s_elemental_data *ed, map_session_data *sd, t_ return 1; } - if( battle_check_range(&ed->bl,target,view_range) && rnd()%100 < 2 ) { // 2% chance to cast attack skill. + if( battle_check_range(&ed->bl,target,view_range) && rnd_chance(2, 100) ) { // 2% chance to cast attack skill. if( elemental_action(ed,target,tick) ) return 1; } diff --git a/src/map/itemdb.cpp b/src/map/itemdb.cpp index 41da7e575a..cdc221c4ca 100644 --- a/src/map/itemdb.cpp +++ b/src/map/itemdb.cpp @@ -2872,7 +2872,7 @@ std::shared_ptr get_random_itemsubgroup(std::shared_ptrdata.size() * 3; j < max; j++) { std::shared_ptr entry = util::umap_random(random->data); - if (entry->rate == 0 || rnd() % random->total_rate < entry->rate) // always return entry for rate 0 ('must' item) + if (entry->rate == 0 || rnd_chance(entry->rate, random->total_rate)) // always return entry for rate 0 ('must' item) return entry; } @@ -2956,9 +2956,9 @@ static void itemdb_pc_get_itemgroup_sub(map_session_data *sd, bool identify, std if( data->refineMinimum > 0 && data->refineMaximum > 0 ){ tmp.refine = rnd_value( data->refineMinimum, data->refineMaximum ); }else if( data->refineMinimum > 0 ){ - tmp.refine = rnd_value( data->refineMinimum, MAX_REFINE ); + tmp.refine = rnd_value( data->refineMinimum, MAX_REFINE ); }else if( data->refineMaximum > 0 ){ - tmp.refine = rnd_value( 1, data->refineMaximum ); + tmp.refine = rnd_value( 1, data->refineMaximum ); }else{ tmp.refine = 0; } @@ -4456,7 +4456,7 @@ void s_random_opt_group::apply( struct item& item ){ for( size_t j = 0, max = this->slots[static_cast(i)].size() * 3; j < max; j++ ){ std::shared_ptr option = util::vector_random( this->slots[static_cast(i)] ); - if( rnd() % 10000 < option->chance ){ + if ( rnd_chance(option->chance, 10000) ) { apply_sub( item.option[i], option ); break; } @@ -4481,7 +4481,7 @@ void s_random_opt_group::apply( struct item& item ){ std::shared_ptr option = util::vector_random( this->random_options ); - if( rnd() % 10000 < option->chance ){ + if ( rnd_chance(option->chance, 10000) ){ apply_sub( item.option[i], option ); } } diff --git a/src/map/map.cpp b/src/map/map.cpp index cc4b1adf13..2d7331c00d 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -1669,7 +1669,7 @@ int map_searchrandfreecell(int16 m,int16 *x,int16 *y,int stack) { } if(free_cell==0) return 0; - free_cell = rnd()%free_cell; + free_cell = rnd_value(0, free_cell-1); *x = free_cells[free_cell][0]; *y = free_cells[free_cell][1]; return 1; @@ -1697,8 +1697,6 @@ int map_search_freecell(struct block_list *src, int16 m, int16 *x,int16 *y, int1 { int tries, spawn=0; int bx, by; - int rx2 = 2*rx+1; - int ry2 = 2*ry+1; if( !src && (!(flag&1) || flag&2) ) { @@ -1728,7 +1726,7 @@ int map_search_freecell(struct block_list *src, int16 m, int16 *x,int16 *y, int1 } if (rx >= 0 && ry >= 0) { - tries = rx2*ry2; + tries = (rx * 2 + 1) * (ry * 2 + 1); if (tries > 100) tries = 100; } else { tries = mapdata->xs*mapdata->ys; @@ -1736,8 +1734,8 @@ int map_search_freecell(struct block_list *src, int16 m, int16 *x,int16 *y, int1 } while(tries--) { - *x = (rx >= 0)?(rnd()%rx2-rx+bx):(rnd()%(mapdata->xs-2)+1); - *y = (ry >= 0)?(rnd()%ry2-ry+by):(rnd()%(mapdata->ys-2)+1); + *x = (rx >= 0) ? rnd_value(bx - rx, bx + rx) : rnd_value(1, mapdata->xs - 1); + *y = (ry >= 0) ? rnd_value(by - ry, by + ry) : rnd_value(1, mapdata->ys - 1); if (*x == bx && *y == by) continue; //Avoid picking the same target tile. @@ -1860,7 +1858,6 @@ bool map_closest_freecell(int16 m, int16 *x, int16 *y, int type, int flag) *------------------------------------------*/ int map_addflooritem(struct item *item, int amount, int16 m, int16 x, int16 y, int first_charid, int second_charid, int third_charid, int flags, unsigned short mob_id, bool canShowEffect) { - int r; struct flooritem_data *fitem = NULL; nullpo_ret(item); @@ -1870,7 +1867,6 @@ int map_addflooritem(struct item *item, int amount, int16 m, int16 x, int16 y, i if (!map_searchrandfreecell(m,&x,&y,flags&2?1:0)) return 0; - r = rnd(); CREATE(fitem, struct flooritem_data, 1); fitem->bl.type=BL_ITEM; @@ -1894,8 +1890,8 @@ int map_addflooritem(struct item *item, int amount, int16 m, int16 x, int16 y, i memcpy(&fitem->item,item,sizeof(*item)); fitem->item.amount = amount; - fitem->subx = (r&3)*3+3; - fitem->suby = ((r>>2)&3)*3+3; + fitem->subx = rnd_value(1, 4) * 3; + fitem->suby = rnd_value(1, 4) * 3; fitem->cleartimer = add_timer(gettick()+battle_config.flooritem_lifetime,map_clearflooritem_timer,fitem->bl.id,0); map_addiddb(&fitem->bl); @@ -3090,8 +3086,8 @@ int map_random_dir(struct block_list *bl, int16 *x, int16 *y) if (dist < 1) dist =1; do { - short j = 1 + 2*(rnd()%4); //Pick a random diagonal direction - short segment = 1+(rnd()%dist); //Pick a random interval from the whole vector in that direction + directions j = static_cast(1 + 2 * rnd_value(0, 3)); //Pick a random diagonal direction + short segment = rnd_value((short)1, dist); //Pick a random interval from the whole vector in that direction xi = bl->x + segment*dirx[j]; segment = (short)sqrt((float)(dist2 - segment*segment)); //The complement of the previously picked segment yi = bl->y + segment*diry[j]; @@ -5181,7 +5177,6 @@ bool MapServer::initialize( int argc, char *argv[] ){ #endif cli_get_options(argc,argv); - rnd_init(); map_config_read(MAP_CONF_NAME); if (save_settings == CHARSAVE_NONE) diff --git a/src/map/mercenary.cpp b/src/map/mercenary.cpp index 1e6def5fce..eceb10f5c7 100644 --- a/src/map/mercenary.cpp +++ b/src/map/mercenary.cpp @@ -421,7 +421,7 @@ bool mercenary_dead(s_mercenary_data *md) { void mercenary_killbonus(s_mercenary_data *md) { std::vector scs = { SC_MERC_FLEEUP, SC_MERC_ATKUP, SC_MERC_HPUP, SC_MERC_SPUP, SC_MERC_HITUP }; - sc_start(&md->bl,&md->bl, util::vector_random(scs), 100, rnd() % 5, 600000); + sc_start(&md->bl,&md->bl, util::vector_random(scs), 100, rnd_value(1, 5), 600000); } /** diff --git a/src/map/party.cpp b/src/map/party.cpp index 5371c75c18..9e3b6750ef 100644 --- a/src/map/party.cpp +++ b/src/map/party.cpp @@ -1278,7 +1278,7 @@ int party_share_loot(struct party_data* p, map_session_data* sd, struct item* it } while (count > 0) { //Pick a random member. - i = rnd()%count; + i = rnd_value(0, count-1); if (pc_additem(psd[i],item,item->amount,LOG_TYPE_PICKDROP_PLAYER)) { // Discard this receiver. psd[i] = psd[count-1]; diff --git a/src/map/path.cpp b/src/map/path.cpp index 29b3c120e6..35f59715da 100644 --- a/src/map/path.cpp +++ b/src/map/path.cpp @@ -106,7 +106,7 @@ int path_blownpos(int16 m,int16 x0,int16 y0,int16 dx,int16 dy,int count) int fy = ( dy != 0 && map_getcellp(mapdata,x0,y0+dy,CELL_CHKPASS) ); if( fx && fy ) { - if(rnd()&1) + if(rnd_chance(50, 100)) dx=0; else dy=0; diff --git a/src/map/pet.cpp b/src/map/pet.cpp index 6d1c595036..016f0ff472 100644 --- a/src/map/pet.cpp +++ b/src/map/pet.cpp @@ -710,7 +710,7 @@ int pet_attackskill(struct pet_data *pd, int target_id) if (DIFF_TICK(pd->ud.canact_tick, gettick()) > 0) return 0; - if (rnd()%100 < (pd->a_skill->rate +pd->pet.intimate*pd->a_skill->bonusrate/1000)) { // Skotlex: Use pet's skill + if (rnd_chance((pd->a_skill->rate +pd->pet.intimate*pd->a_skill->bonusrate/1000), 100)) { // Skotlex: Use pet's skill int inf; struct block_list *bl; @@ -782,8 +782,8 @@ int pet_target_check(struct pet_data *pd,struct block_list *bl,int type) rate = 1; } - if(rnd()%10000 < rate) { - if(pd->target_id == 0 || rnd()%10000 < pet_db_ptr->change_target_rate) + if(rnd_chance(rate, 10000)) { + if(pd->target_id == 0 || rnd_chance(pet_db_ptr->change_target_rate, 10000)) pd->target_id = bl->id; } @@ -942,7 +942,7 @@ static int pet_performance(map_session_data *sd, struct pet_data *pd) val = 1; pet_stop_walking(pd,2000<<8); - clif_pet_performance(pd, rnd()%val + 1); + clif_pet_performance(pd, rnd_value(1, val)); pet_lootitem_drop(pd,NULL); return 1; @@ -1315,7 +1315,7 @@ int pet_catch_process2(map_session_data* sd, int target_id) if(battle_config.pet_catch_rate != 100) pet_catch_rate = (pet_catch_rate*battle_config.pet_catch_rate)/100; - if(rnd()%10000 < pet_catch_rate) { + if(rnd_chance(pet_catch_rate, 10000)) { achievement_update_objective(sd, AG_TAMING, 1, md->mob_id); unit_remove_map(&md->bl,CLR_OUTSIGHT); status_kill(&md->bl); @@ -1672,10 +1672,10 @@ static int pet_randomwalk(struct pet_data *pd,t_tick tick) d = 5; for(i = 0; i < retrycount; i++) { - int r = rnd(), x, y; + int x, y; - x = pd->bl.x+r%(d*2+1)-d; - y = pd->bl.y+r/(d*2+1)%(d*2+1)-d; + x = pd->bl.x + rnd_value(-d, d); + y = pd->bl.y + rnd_value(-d, d); if(map_getcell(pd->bl.m,x,y,CELL_CHKPASS) && unit_walktoxy(&pd->bl,x,y,0)) { pd->move_fail_count = 0; @@ -1702,7 +1702,7 @@ static int pet_randomwalk(struct pet_data *pd,t_tick tick) c += pd->status.speed; } - pd->next_walktime = tick+rnd()%1000+MIN_RANDOMWALKTIME+c; + pd->next_walktime = tick + MIN_RANDOMWALKTIME + c + rnd_value(0, 999); return 1; } diff --git a/src/map/quest.cpp b/src/map/quest.cpp index 1707859e44..0624710818 100644 --- a/src/map/quest.cpp +++ b/src/map/quest.cpp @@ -775,7 +775,7 @@ void quest_update_objective(map_session_data *sd, struct mob_data* md) for (const auto &it : qi->dropitem) { if (it->mob_id != 0 && it->mob_id != md->mob_id) continue; - if (it->rate < 10000 && rnd()%10000 >= it->rate) + if (it->rate < 10000 && !rnd_chance(it->rate, 10000)) continue; // TODO: Should this be affected by server rates? if (!item_db.exists(it->nameid)) continue; diff --git a/src/map/script.cpp b/src/map/script.cpp index 0bfe6c4241..a9e632dd1b 100644 --- a/src/map/script.cpp +++ b/src/map/script.cpp @@ -5582,17 +5582,17 @@ BUILDIN_FUNC(rand) min = script_getnum(st,2); if( max < min ) SWAP(min, max); - range = max - min + 1; + range = max; } else {// range min = 0; - range = script_getnum(st,2); + range = script_getnum( st, 2 ) - 1; } if( range <= 1 ) script_pushint(st, min); else - script_pushint(st, rnd()%range + min); + script_pushint( st, rnd_value( min, range ) ); return SCRIPT_CMD_SUCCESS; } @@ -5656,8 +5656,8 @@ static int buildin_areawarp_sub(struct block_list *bl,va_list ap) // find a suitable map cell do { - tx = rnd()%(x3-x2+1)+x2; - ty = rnd()%(y3-y2+1)+y2; + tx = rnd_value(x2, x3); + ty = rnd_value(y2, y3); j++; } while( map_getcell(m,tx,ty,CELL_CHKNOPASS) && j < max ); @@ -5815,8 +5815,8 @@ BUILDIN_FUNC(warpparty) i = 0; do { - x = rnd()%(mapdata->xs - 2) + 1; - y = rnd()%(mapdata->ys - 2) + 1; + x = rnd_value(1, mapdata->xs - 1); + y = rnd_value(1, mapdata->ys - 1); } while ((map_getcell(m,x,y,CELL_CHKNOPASS) || (!battle_config.teleport_on_portal && npc_check_areanpc(1,m,x,y,1))) && (i++) < 1000); if (i >= 1000) { @@ -5881,8 +5881,8 @@ BUILDIN_FUNC(warpparty) uint8 attempts = 10; do { - nx = x0 + rnd()%(x1 - x0 + 1); - ny = y0 + rnd()%(y1 - y0 + 1); + nx = x0 + rnd_value(x0, x1); + ny = y0 + rnd_value(y0, y1); } while ((--attempts) > 0 && !map_getcell(m, nx, ny, CELL_CHKPASS)); if (attempts != 0) { //Keep the original coordinates if fails to find a valid cell within the range @@ -10693,8 +10693,8 @@ BUILDIN_FUNC(savepoint) x0 = x - dx, y0 = y - dy; uint8 n = 10; do { - x = x0 + rnd()%(x1-x0+1); - y = y0 + rnd()%(y1-y0+1); + x = rnd_value(x0, x1); + y = rnd_value(y0, y1); } while (m != -1 && (--n) > 0 && !map_getcell(m, x, y, CELL_CHKPASS)); } @@ -12536,7 +12536,7 @@ BUILDIN_FUNC(homunculus_evolution) *------------------------------------------*/ BUILDIN_FUNC(homunculus_mutate) { - int homun_id; + uint16 homun_id; TBL_PC *sd; if( !script_rid2sd(sd) || sd->hd == NULL ) @@ -12545,7 +12545,7 @@ BUILDIN_FUNC(homunculus_mutate) if(script_hasdata(st,2)) homun_id = script_getnum(st,2); else - homun_id = 6048 + (rnd() % 4); + homun_id = rnd_value(MER_EIRA, MER_ELEANOR); if( sd->hd->homunculus.vaporize == HOM_ST_MORPH ) { int m_class = hom_class2mapid(sd->hd->homunculus.class_); diff --git a/src/map/skill.cpp b/src/map/skill.cpp index b41c116195..25d61e1b71 100755 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -1927,7 +1927,7 @@ int skill_additional_effect( struct block_list* src, struct block_list *bl, uint break; case LG_HESPERUSLIT: if( pc_checkskill(sd,LG_PINPOINTATTACK) > 0 && sc && sc->getSCE(SC_BANDING) && sc->getSCE(SC_BANDING)->val2 > 5 ) - skill_castend_damage_id(src,bl,LG_PINPOINTATTACK,rnd_value(1, pc_checkskill(sd,LG_PINPOINTATTACK)),tick,0); + skill_castend_damage_id(src,bl,LG_PINPOINTATTACK, rnd_value(1, pc_checkskill(sd,LG_PINPOINTATTACK)),tick,0); break; case SR_DRAGONCOMBO: sc_start(src,bl, SC_STUN, 1 + skill_lv, skill_lv, skill_get_time(skill_id, skill_lv)); @@ -2332,7 +2332,7 @@ int skill_additional_effect( struct block_list* src, struct block_list *bl, uint uint16 autospl_skill_lv = it.lv ? it.lv : 1; if (it.flag & AUTOSPELL_FORCE_RANDOM_LEVEL) - autospl_skill_lv = rnd_value( 1, autospl_skill_lv ); + autospl_skill_lv = rnd_value( 1, autospl_skill_lv ); int rate = (!sd->state.arrow_atk) ? it.rate : it.rate / 2; @@ -2479,7 +2479,7 @@ int skill_onskillusage(map_session_data *sd, struct block_list *bl, uint16 skill uint16 skill_lv = it.lv ? it.lv : 1; if (it.flag & AUTOSPELL_FORCE_RANDOM_LEVEL) - skill_lv = rnd_value( 1, skill_lv ); //random skill_lv + skill_lv = rnd_value( 1, skill_lv ); //random skill_lv e_cast_type type = skill_get_casttype(skill); @@ -2699,7 +2699,7 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list * uint16 autospl_skill_id = it.id, autospl_skill_lv = it.lv ? it.lv : 1; if (it.flag & AUTOSPELL_FORCE_RANDOM_LEVEL) - autospl_skill_lv = rnd_value( 1, autospl_skill_lv ); + autospl_skill_lv = rnd_value( 1, autospl_skill_lv ); int autospl_rate = it.rate; diff --git a/src/map/unit.cpp b/src/map/unit.cpp index 37274303a7..8ed24b3b57 100644 --- a/src/map/unit.cpp +++ b/src/map/unit.cpp @@ -2603,7 +2603,7 @@ int unit_calc_pos(struct block_list *bl, int tx, int ty, uint8 dir) nullpo_ret(ud); - if(dir > 7) + if(dir >= DIR_MAX || dir <= DIR_CENTER) return 1; ud->to_x = tx; @@ -2630,7 +2630,7 @@ int unit_calc_pos(struct block_list *bl, int tx, int ty, uint8 dir) int i; for( i = 0; i < 12; i++ ) { - int k = rnd()%8; // Pick a Random Dir + int k = rnd_value(DIR_NORTH, DIR_NORTHEAST); // Pick a Random Dir dx = -dirx[k] * 2; dy = -diry[k] * 2;