Merge remote-tracking branch 'upstream/master' into refactor/cmake

This commit is contained in:
Vincent Stumpf 2023-12-24 00:26:14 +00:00
commit 008d25cfb2
46 changed files with 9440 additions and 444 deletions

View File

@ -365,6 +365,10 @@ Body:
Help: |
Params: [<item type>]
Throws all your possession on the ground. No type specified will drop all items.
- Command: stockall
Help: |
Params: [<item type>]
Transfer items from cart to your inventory. No type specified will transfer all items.
- Command: storeall
Help: |
Puts all your possessions in storage.

View File

@ -1815,5 +1815,10 @@
1531: Invalid position.
1532: Invalid slot number.
//@stockall
1533: You do not have a cart.
1534: Usage: @stockall {<type>}
1535: %d items are transferred (%d skipped)!
//Custom translations
import: conf/msg_conf/import/map_msg_eng_conf.txt

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -66932,6 +66932,15 @@ Body:
Container: true
Script: |
getgroupitem(IG_Ponytail_Hair_Box);
- Id: 102605
AegisName: aegis_102605
Name: Costume Enchant Stone Box 33
Type: Usable
Weight: 10
Flags:
Container: true
Script: |
getgroupitem(IG_Enchant_Stone_Box33);
- Id: 200003
AegisName: LI_HD_Oridecon_Box2
Name: (Limited) HD Oridecon Box(Blacksmith)(30)

View File

@ -73781,3 +73781,205 @@ Body:
- Index: 23
Item: C_Blackhand_Of_Fate
Rate: 1
- Group: ENCHANT_STONE_BOX33
SubGroups:
- SubGroup: 1
List:
- Index: 0
Item: Range_Stone_Robe_D
Rate: 10
- Index: 1
Item: Melee_Stone_Robe_D
Rate: 10
- Index: 2
Item: Magic_Stone_Robe_D
Rate: 10
- Index: 3
Item: SmatkStone_Robe
Rate: 10
- Index: 4
Item: M_PATKStone_Robe
Rate: 10
- Index: 5
Item: R_PATKStone_Robe
Rate: 10
- Index: 6
Item: ResistDefStone_Robe
Rate: 10
- Index: 7
Item: StaminaWISStone_Robe_D
Rate: 10
- Index: 8
Item: POWStone_Robe_D
Rate: 10
- Index: 9
Item: SplStone_Robe_D
Rate: 10
- Index: 10
Item: ConStone_Robe_D
Rate: 10
- Index: 11
Item: CrtStone_Robe_D
Rate: 10
- Index: 12
Item: MinorCastStone_Robe_D
Rate: 10
- Index: 13
Item: AbysschaserStone_Robe
Rate: 10
- Index: 14
Item: TRTRStone_Robe
Rate: 10
- Index: 15
Item: HNoviceStone_Robe
Rate: 10
- Index: 16
Item: ReloadStone_Robe_D
Rate: 10
- Index: 17
Item: CriticalStone_Robe_D
Rate: 10
- Index: 18
Item: DoubleAttack_Stone
Rate: 20
- Index: 19
Item: Critical_Stone_Robe
Rate: 20
- Index: 20
Item: CastStone_Robe_D
Rate: 40
- Index: 21
Item: SPdrainStone_Robe_D
Rate: 40
- Index: 22
Item: HPdrainStone_Robe_D
Rate: 80
- Index: 23
Item: ASPDStone_Robe_D
Rate: 80
- Index: 24
Item: CastStone_Robe
Rate: 80
- Index: 25
Item: ShadowchasStone_Top3
Rate: 80
- Index: 26
Item: ShadowchasStone_Middle3
Rate: 80
- Index: 27
Item: ShadowchasStone_Bottom3
Rate: 80
- Index: 28
Item: WanderMinsStone_Top3
Rate: 80
- Index: 29
Item: WanderMinsStone_Middle3
Rate: 80
- Index: 30
Item: WanderMinsStone_Bottom3
Rate: 80
- Index: 31
Item: SuNoviceStone_Top
Rate: 80
- Index: 32
Item: SuNoviceStone_Middle
Rate: 80
- Index: 33
Item: SuNoviceStone_Bottom
Rate: 80
- Index: 34
Item: Stone_Robe_Box
Rate: 170
- Index: 35
Item: aegis_102333
Rate: 170
- Index: 36
Item: Magic_Stone_Top
Rate: 200
- Index: 37
Item: Magic_Stone_Middle
Rate: 200
- Index: 38
Item: Magic_Stone_Bottom
Rate: 200
- Index: 39
Item: Range_Stone_Top
Rate: 200
- Index: 40
Item: Range_Stone
Rate: 200
- Index: 41
Item: Range_Stone_Bottom
Rate: 200
- Index: 42
Item: Melee_Stone_Top
Rate: 200
- Index: 43
Item: Melee_Stone_Middle
Rate: 200
- Index: 44
Item: Melee_Stone_Bottom
Rate: 200
- Index: 45
Item: DefenseStone_Top
Rate: 200
- Index: 46
Item: DefenseStone_Middle
Rate: 200
- Index: 47
Item: DefenseStone_Bottom
Rate: 200
- Index: 48
Item: ReloadStone_Top
Rate: 200
- Index: 49
Item: ReloadStone_Middle
Rate: 200
- Index: 50
Item: ReloadStone_Bottom
Rate: 200
- Index: 51
Item: EXPStone_Middle
Rate: 200
- Index: 52
Item: EXPStone_Bottom
Rate: 200
- Index: 53
Item: EXPStone_Top
Rate: 200
- Index: 54
Item: Stone_Top_Box
Rate: 400
- Index: 55
Item: Stone_Top2_Box
Rate: 400
- Index: 56
Item: Stone_Middle_Box
Rate: 400
- Index: 57
Item: Stone_Middle2_Box
Rate: 400
- Index: 58
Item: Stone_Bottom_Box
Rate: 400
- Index: 59
Item: Stone_Bottom2_Box
Rate: 400
- Index: 60
Item: CastingStone_Top
Rate: 400
- Index: 61
Item: CastingStone_Middle
Rate: 400
- Index: 62
Item: CastingStone_Bottom
Rate: 400
- Index: 63
Item: Critical_Stone
Rate: 400
- Index: 64
Item: Critical_Stone_Top
Rate: 400
- Index: 65
Item: Critical_Stone_Bottom
Rate: 400

View File

@ -94088,6 +94088,8 @@ Body:
ChaseRange: 12
Size: Small
Race: Insect
RaceGroups:
Illusion_Luanda: true
Element: Earth
ElementLevel: 1
WalkSpeed: 200
@ -94135,6 +94137,8 @@ Body:
ChaseRange: 12
Size: Large
Race: Formless
RaceGroups:
Illusion_Luanda: true
Element: Neutral
ElementLevel: 4
WalkSpeed: 150
@ -94182,6 +94186,8 @@ Body:
ChaseRange: 12
Size: Large
Race: Formless
RaceGroups:
Illusion_Luanda: true
Element: Neutral
ElementLevel: 4
WalkSpeed: 200
@ -94227,6 +94233,8 @@ Body:
ChaseRange: 12
Size: Large
Race: Demon
RaceGroups:
Illusion_Luanda: true
Element: Neutral
ElementLevel: 3
WalkSpeed: 150
@ -94277,6 +94285,8 @@ Body:
ChaseRange: 12
Size: Medium
Race: Plant
RaceGroups:
Illusion_Luanda: true
Element: Fire
ElementLevel: 3
WalkSpeed: 175
@ -94324,6 +94334,8 @@ Body:
ChaseRange: 12
Size: Medium
Race: Demihuman
RaceGroups:
Illusion_Luanda: true
Element: Earth
ElementLevel: 2
WalkSpeed: 200
@ -94371,6 +94383,8 @@ Body:
ChaseRange: 12
Size: Medium
Race: Demihuman
RaceGroups:
Illusion_Luanda: true
Element: Fire
ElementLevel: 2
WalkSpeed: 200
@ -94418,6 +94432,8 @@ Body:
ChaseRange: 12
Size: Large
Race: Demihuman
RaceGroups:
Illusion_Luanda: true
Element: Fire
ElementLevel: 4
WalkSpeed: 150

View File

@ -14252,7 +14252,7 @@
20943,DEATH_WITCH@NPC_PULSESTRIKE,attack,661,5,2000,0,30000,yes,self,always,0,,,,,,32,
20943,DEATH_WITCH@HW_GANBANTEIN,attack,483,1,2000,0,5000,yes,target,always,0,,,,,,,
// 20943,DEATH_WITCH@NPC_EARTHQUAKE_K,attack,750,5,10000,1500,25000,no,target,myhpltmaxrate,20,,,,,,,
20943,DEATH_WITCH@NPC_EARTHQUAKE,attack,653,5,10000,1500,25000,no,target,myhpltmaxrate,20,,,,,,,
20943,DEATH_WITCH@NPC_EARTHQUAKE,attack,653,5,10000,1500,25000,no,self,myhpltmaxrate,20,,,,,,,
20943,DEATH_WITCH@NPC_HELLJUDGEMENT,chase,662,2,2000,500,5000,no,self,always,0,,,,,,,
20943,DEATH_WITCH@NPC_HELLJUDGEMENT,attack,662,2,2000,500,5000,no,self,always,0,,,,,,,
20943,DEATH_WITCH@NPC_CLOUD_KILL,attack,739,5,2000,500,16000,no,target,always,0,,,,,,,
@ -14320,7 +14320,7 @@
20928,CHIMERA_THEONE@WZ_WATERBALL,chase,86,5,5000,1000,35000,no,target,always,0,,,,,,,
// TODO
// 20928,CHIMERA_THEONE@NPC_EARTHQUAKE_K,chase,750,5,10000,500,20000,no,target,myhpltmaxrate,40,,,,,,,
20928,CHIMERA_THEONE@NPC_EARTHQUAKE,chase,653,5,10000,500,20000,no,target,myhpltmaxrate,40,,,,,,,
20928,CHIMERA_THEONE@NPC_EARTHQUAKE,chase,653,5,10000,500,20000,no,self,myhpltmaxrate,40,,,,,,,
20928,CHIMERA_THEONE@NPC_CALLSLAVE,attack,352,1,10000,0,30000,yes,self,always,0,,,,,,,
20928,CHIMERA_THEONE@NPC_SUMMONSLAVE,attack,196,1,10000,700,10000,no,self,slavele,2,20920,20921,20922,20923,,,
20928,CHIMERA_THEONE@NPC_GROUNDATTACK,attack,185,3,500,0,5000,yes,target,always,0,,,,,,6,

View File

@ -780,6 +780,28 @@ To drop all weapons in inventory...
---------------------------------------
@stockall {<item type>}
Transfer all items from cart to inventory based on the item type.
Valid item types:
-1 = All (default)
0 = Healing
2 = Usable
3 = Etc
4 = Armors
5 = Weapons
6 = Cards
7 = Pet Eggs
8 = Pet Armors
10 = Ammunition
Example:
To transfer all weapons from cart to inventory...
@stockall 5
---------------------------------------
@storeall
Places all inventory and equipped items directly into your Kafra Storage.

View File

@ -15,7 +15,7 @@ This list contains all available constants referenced in the 'bonus' commands.
* Status effect (eff)
Eff_Bleeding, Eff_Blind, Eff_Burning, Eff_Confusion, Eff_Crystalize, Eff_Curse, Eff_DPoison,
Eff_Fear, Eff_Freeze, Eff_Poison, Eff_Silence, Eff_Sleep, Eff_Stone, Eff_Stun, Eff_Freezing,
Eff_Heat, Eff_Deepsleep, Eff_WhiteImprison
Eff_Heat, Eff_Deepsleep, Eff_WhiteImprison, Eff_Hallucination
* Element (e)
Ele_Dark, Ele_Earth, Ele_Fire, Ele_Ghost, Ele_Holy, Ele_Neutral, Ele_Poison,
@ -31,7 +31,7 @@ This list contains all available constants referenced in the 'bonus' commands.
RC2_Bio5_Swordman_Thief, RC2_Bio5_Acolyte_Merchant, RC2_Bio5_Mage_Archer, RC2_Bio5_MVP,
RC2_Clocktower, RC2_Thanatos, RC2_Faceworm, RC2_Hearthunter, RC2_Rockridge, RC2_Werner_Lab,
RC2_Temple_Demon, RC2_Illusion_Vampire, RC2_Malangdo, RC2_EP172ALPHA, RC2_EP172BETA, RC2_EP172BATH,
RC2_Illusion_Turtle, RC2_Rachel_Sanctuary
RC2_Illusion_Turtle, RC2_Rachel_Sanctuary, RC2_Illusion_Luanda
* Class (c)
Class_Normal, Class_Boss, Class_Guardian, Class_All

View File

@ -11390,3 +11390,18 @@ Returns current autoloot value on success.
---------------------------------------
*autoloot({<rate>{, <char_id>}});
This command sets the rate of autoloot.
If no rate is provided and the user has autoloot disabled it will default to 10000 = 100% (enabled) or
if the user has autoloot enabled it will default to 0 = 0% (disabled).
Returns true on success and false on failure.
Example:
autoloot(); // toggle on/off depend on existing autoloot
autoloot(0); // 0.00% or off
autoloot(100); // 1.00%
autoloot(3333); // 33.33%
autoloot(10000); // 100.00%
---------------------------------------

View File

@ -62,6 +62,7 @@ CREATE TABLE `mob_db` (
`racegroup_ep172bath` tinyint(1) unsigned DEFAULT NULL,
`racegroup_illusion_turtle` tinyint(1) unsigned DEFAULT NULL,
`racegroup_rachel_sanctuary` tinyint(1) unsigned DEFAULT NULL,
`racegroup_illusion_luanda` tinyint(1) unsigned DEFAULT NULL,
`element` varchar(24) DEFAULT NULL,
`element_level` tinyint(4) unsigned DEFAULT NULL,
`walk_speed` smallint(6) unsigned DEFAULT NULL,

View File

@ -62,6 +62,7 @@ CREATE TABLE `mob_db2` (
`racegroup_ep172bath` tinyint(1) unsigned DEFAULT NULL,
`racegroup_illusion_turtle` tinyint(1) unsigned DEFAULT NULL,
`racegroup_rachel_sanctuary` tinyint(1) unsigned DEFAULT NULL,
`racegroup_illusion_luanda` tinyint(1) unsigned DEFAULT NULL,
`element` varchar(24) DEFAULT NULL,
`element_level` tinyint(4) unsigned DEFAULT NULL,
`walk_speed` smallint(6) unsigned DEFAULT NULL,

View File

@ -64,6 +64,7 @@ CREATE TABLE `mob_db2_re` (
`racegroup_ep172bath` tinyint(1) unsigned DEFAULT NULL,
`racegroup_illusion_turtle` tinyint(1) unsigned DEFAULT NULL,
`racegroup_rachel_sanctuary` tinyint(1) unsigned DEFAULT NULL,
`racegroup_illusion_luanda` tinyint(1) unsigned DEFAULT NULL,
`element` varchar(24) DEFAULT NULL,
`element_level` tinyint(4) unsigned DEFAULT NULL,
`walk_speed` smallint(6) unsigned DEFAULT NULL,

View File

@ -64,6 +64,7 @@ CREATE TABLE `mob_db_re` (
`racegroup_ep172bath` tinyint(1) unsigned DEFAULT NULL,
`racegroup_illusion_turtle` tinyint(1) unsigned DEFAULT NULL,
`racegroup_rachel_sanctuary` tinyint(1) unsigned DEFAULT NULL,
`racegroup_illusion_luanda` tinyint(1) unsigned DEFAULT NULL,
`element` varchar(24) DEFAULT NULL,
`element_level` tinyint(4) unsigned DEFAULT NULL,
`walk_speed` smallint(6) unsigned DEFAULT NULL,

View File

@ -0,0 +1,12 @@
ALTER TABLE `mob_db`
ADD COLUMN `racegroup_illusion_luanda` tinyint(1) unsigned DEFAULT NULL
;
ALTER TABLE `mob_db2`
ADD COLUMN `racegroup_illusion_luanda` tinyint(1) unsigned DEFAULT NULL
;
ALTER TABLE `mob_db_re`
ADD COLUMN `racegroup_illusion_luanda` tinyint(1) unsigned DEFAULT NULL
;
ALTER TABLE `mob_db2_re`
ADD COLUMN `racegroup_illusion_luanda` tinyint(1) unsigned DEFAULT NULL
;

View File

@ -3,43 +3,9 @@
#include "random.hpp"
#include <random>
std::mt19937 generator;
std::uniform_int_distribution<int32> int31_distribution;
std::uniform_int_distribution<uint32> 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<int32>( 0, SINT32_MAX );
uint32_distribution = std::uniform_int_distribution<uint32>( 0, UINT32_MAX );
}
std::uniform_int_distribution<int32> int31_distribution = std::uniform_int_distribution<int32>(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 ) );
}

View File

@ -4,15 +4,33 @@
#ifndef RANDOM_HPP
#define RANDOM_HPP
#include <type_traits>
#include <random>
#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 <typename T> 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 T>
typename std::enable_if<std::is_integral<T>::value, T>::type rnd_value(T min, T max) {
std::uniform_int_distribution<T> 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 T>
typename std::enable_if<std::is_integral<T>::value, bool>::type rnd_chance(T chance, T base) {
return rnd_value<T>(1, base) <= chance;
}
#endif /* RANDOM_HPP */

View File

@ -159,7 +159,7 @@ namespace rathena {
template <typename K, typename V> V& umap_random( std::unordered_map<K, V>& map ){
auto it = map.begin();
std::advance( it, rnd_value( 0, map.size() - 1 ) );
std::advance( it, rnd_value<size_t>( 0, map.size() - 1 ) );
return it->second;
}
@ -172,7 +172,7 @@ namespace rathena {
template <typename K> K &vector_random(std::vector<K> &vec) {
auto it = vec.begin();
std::advance(it, rnd_value(0, vec.size() - 1));
std::advance( it, rnd_value<size_t>( 0, vec.size() - 1 ) );
return *it;
}

View File

@ -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();

View File

@ -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

View File

@ -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);

View File

@ -5960,6 +5960,62 @@ ACMD_FUNC(dropall)
return 0;
}
/*==========================================
* @stockall by [Hanashi]
* transfer items from cart to inventory
*------------------------------------------*/
ACMD_FUNC(stockall)
{
nullpo_retr(-1, sd);
if (!pc_iscarton(sd)) {
clif_displaymessage(fd, msg_txt(sd,1533)); // You do not have a cart.
return -1;
}
int8 type = -1;
if ( message[0] ) {
type = atoi(message);
switch (type) {
case -1:
case IT_HEALING:
case IT_USABLE:
case IT_ETC:
case IT_WEAPON:
case IT_ARMOR:
case IT_CARD:
case IT_PETEGG:
case IT_PETARMOR:
case IT_AMMO:
break;
default:
clif_displaymessage(fd, msg_txt(sd, 1534)); // Usage: @stockall {<type>}
clif_displaymessage(fd, msg_txt(sd, 1493)); // Type List: (default) all = -1, healing = 0, usable = 2, etc = 3, armor = 4, weapon = 5, card = 6, petegg = 7, petarmor = 8, ammo = 10
return -1;
}
}
uint16 count = 0, count2 = 0;
for ( uint16 i = 0; i < MAX_CART; i++ ) {
if ( sd->cart.u.items_cart[i].amount > 0 ) {
std::shared_ptr<item_data> id = item_db.find(sd->cart.u.items_cart[i].nameid);
if ( id == nullptr ) {
ShowDebug("Non-existent item %u on stockall list (account_id: %d, char_id: %d)\n", sd->cart.u.items_cart[i].nameid, sd->status.account_id, sd->status.char_id);
continue;
}
if ( type == -1 || static_cast<item_types>(type) == id->type ) {
if (pc_getitemfromcart(sd, i, sd->cart.u.items_cart[i].amount))
count += sd->cart.u.items_cart[i].amount;
else
count2 += sd->cart.u.items_cart[i].amount;
}
}
}
sprintf(atcmd_output, msg_txt(sd,1535), count,count2); // %d items are transferred (%d skipped)!
clif_displaymessage(fd, atcmd_output);
return 0;
}
/*==========================================
* @storeall by [MouseJstr]
* Put everything into storage
@ -7203,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<int>(ET_DICE1, ET_DICE6); // randomize /dice
if( i < ARRAYLENGTH(emo) )
{
if (sd->emotionlasttime + 1 >= time(NULL)) { // not more than 1 per second
@ -7961,7 +8017,7 @@ ACMD_FUNC(hommutate)
}
if (!message || !*message) {
homun_id = 6048 + (rnd() % 4);
homun_id = rnd_value<uint16>(MER_EIRA, MER_ELEANOR);
} else {
homun_id = atoi(message);
}
@ -9077,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) {
@ -11078,6 +11134,7 @@ void atcommand_basecommands(void) {
ACMD_DEF(npcmove),
ACMD_DEF(killable),
ACMD_DEF(dropall),
ACMD_DEF(stockall),
ACMD_DEF(storeall),
ACMD_DEF(skillid),
ACMD_DEF(useskill),

View File

@ -1172,7 +1172,7 @@ void bg_queue_join_multi(const char *name, map_session_data *sd, std::vector <ma
break;
}
bool r = rnd() % 2 != 0;
bool r = rnd_chance(50, 100);
std::vector<map_session_data *> *team = r ? &queue->teamb_members : &queue->teama_members;
if (queue->state == QUEUE_STATE_ACTIVE) {

View File

@ -4,6 +4,8 @@
#include "clif.hpp"
#include <unordered_set>
#include <cstdarg>
#include <cstdio>
#include <cstdlib>
@ -20943,69 +20945,95 @@ void clif_merge_item_open( map_session_data& sd ){
}
/**
* Process item merger
* CZ 096E <size>.W { <index>.W }* (CZ_REQ_MERGE_ITEM)
* Process item merge request.
* 096E <size>.W { <index>.W }* (CZ_REQ_MERGE_ITEM)
* @param fd
* @param sd
**/
void clif_parse_merge_item_req( int fd, map_session_data* sd ){
struct s_packet_db *info = NULL;
unsigned short n = 0, indexes[MAX_INVENTORY] = { 0 }, i, j;
unsigned int count = 0;
struct item_data *id = NULL;
struct PACKET_CZ_REQ_MERGE_ITEM* p = (struct PACKET_CZ_REQ_MERGE_ITEM*)RFIFOP( fd, 0 );
nullpo_retv(sd);
if (!clif_session_isValid(sd))
return;
if (!(info = &packet_db[RFIFOW(fd,0)]) || info->len == 0)
return;
int count = ( p->packetLength - sizeof( *p ) ) / sizeof( p->indices[0] );
n = (RFIFOW(fd, info->pos[0]) - 4) / 2;
if (n < 2) { // No item need to be merged
// No item need to be merged
if( count < 2 ){
clif_msg( sd, MERGE_ITEM_NOT_AVAILABLE );
return;
}
for (i = 0, j = 0; i < n; i++) {
uint16 idx = server_index( RFIFOW( fd, info->pos[1] + i * 2 ) );
uint16 idx_main = server_index( p->indices[0] );
if( idx_main >= MAX_INVENTORY ){
return;
}
if( !clif_merge_item_check( sd->inventory_data[idx_main], &sd->inventory.u.items_inventory[idx_main] ) ){
clif_msg( sd, MERGE_ITEM_NOT_AVAILABLE );
return;
}
// Ensure each index only comes once
std::unordered_set<uint16> indices;
for( int i = 1; i < count; i++ ){
uint16 idx = server_index( p->indices[i] );
if( idx >= MAX_INVENTORY ){
return;
}
if (!clif_merge_item_check((id = sd->inventory_data[idx]), &sd->inventory.u.items_inventory[idx]))
continue;
indexes[j] = idx;
if (j && id->nameid != sd->inventory_data[indexes[0]]->nameid) { // Only can merge 1 kind at once
clif_merge_item_ack( *sd, MERGE_ITEM_FAILED_NOT_MERGE );
if( sd->inventory_data[idx] == nullptr ){
return;
}
count += sd->inventory.u.items_inventory[idx].amount;
j++;
// Check if it is the same item
if( sd->inventory_data[idx]->nameid != sd->inventory_data[idx_main]->nameid ){
return;
}
if (n != j || !(id = sd->inventory_data[indexes[0]])) {
if( !clif_merge_item_check( sd->inventory_data[idx], &sd->inventory.u.items_inventory[idx] ) ){
clif_msg( sd, MERGE_ITEM_NOT_AVAILABLE );
return;
}
if (count >= (id->stack.amount ? id->stack.amount : MAX_AMOUNT)) {
indices.insert( idx );
}
if( indices.empty() ){
clif_msg( sd, MERGE_ITEM_NOT_AVAILABLE );
return;
}
uint32 total_amount = sd->inventory.u.items_inventory[idx_main].amount;
for( uint16 idx : indices ){
total_amount += sd->inventory.u.items_inventory[idx].amount;
}
uint16 stack = sd->inventory_data[idx_main]->stack.amount;
if( stack == 0 ){
stack = MAX_AMOUNT;
}
if( total_amount >= stack ){
clif_merge_item_ack( *sd, MERGE_ITEM_FAILED_MAX_COUNT );
return;
}
// Merrrrge!!!!
for (i = 1; i < n; i++) {
unsigned short idx = indexes[i], amt = sd->inventory.u.items_inventory[idx].amount;
log_pick_pc(sd, LOG_TYPE_MERGE_ITEM, -amt, &sd->inventory.u.items_inventory[idx]);
memset(&sd->inventory.u.items_inventory[idx], 0, sizeof(sd->inventory.u.items_inventory[0]));
sd->inventory_data[idx] = NULL;
clif_delitem(sd, idx, amt, 0);
}
sd->inventory.u.items_inventory[indexes[0]].amount = count;
for( uint16 idx : indices ){
uint16 amount = sd->inventory.u.items_inventory[idx].amount;
clif_merge_item_ack( *sd, MERGE_ITEM_SUCCESS, indexes[0], count );
log_pick_pc( sd, LOG_TYPE_MERGE_ITEM, -amount, &sd->inventory.u.items_inventory[idx] );
memset( &sd->inventory.u.items_inventory[idx], 0, sizeof( sd->inventory.u.items_inventory[0] ) );
sd->inventory_data[idx] = nullptr;
clif_delitem( sd, idx, amount, 0 );
}
sd->inventory.u.items_inventory[idx_main].amount = total_amount;
clif_merge_item_ack( *sd, MERGE_ITEM_SUCCESS, idx_main, total_amount );
}
/**
@ -23561,11 +23589,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<uint16>( 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<uint16>( upgrade->resultRefineMinimum, MAX_REFINE );
}
// Log retrieving the item again -> with the new options

View File

@ -1916,7 +1916,7 @@
parseable_packet(0x0916,26,clif_parse_GuildInvite2,2);
parseable_packet(0x091d,41,clif_parse_PartyBookingRegisterReq,2,4,6);
// Merge Item
parseable_packet(0x096E,-1,clif_parse_merge_item_req,2,4); // CZ_REQ_MERGE_ITEM
parseable_packet( HEADER_CZ_REQ_MERGE_ITEM, -1, clif_parse_merge_item_req, 0 );
parseable_packet(0x0974,2,clif_parse_merge_item_cancel,0); // CZ_CANCEL_MERGE_ITEM
parseable_packet(0x0844,2,clif_parse_cashshop_open_request,0);
packet(0x0849,16); //clif_cashshop_result
@ -2061,7 +2061,6 @@
// 2013-08-07Ragexe
#if PACKETVER >= 20130807
// Merge Item
parseable_packet(0x096E,-1,clif_parse_merge_item_req,2,4); // CZ_REQ_MERGE_ITEM
parseable_packet(0x0974,2,clif_parse_merge_item_cancel,0); // CZ_CANCEL_MERGE_ITEM
packet(0x9CD,8); // ZC_MSG_COLOR
#endif

View File

@ -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;
}

View File

@ -2872,7 +2872,7 @@ std::shared_ptr<s_item_group_entry> get_random_itemsubgroup(std::shared_ptr<s_it
for (size_t j = 0, max = random->data.size() * 3; j < max; j++) {
std::shared_ptr<s_item_group_entry> 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<uint32>(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<uint16>( data->refineMinimum, MAX_REFINE );
}else if( data->refineMaximum > 0 ){
tmp.refine = rnd_value( 1, data->refineMaximum );
tmp.refine = rnd_value<uint16>( 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<uint16>(i)].size() * 3; j < max; j++ ){
std::shared_ptr<s_random_opt_group_entry> option = util::vector_random( this->slots[static_cast<uint16>(i)] );
if( rnd() % 10000 < option->chance ){
if ( rnd_chance<uint16>(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<s_random_opt_group_entry> option = util::vector_random( this->random_options );
if( rnd() % 10000 < option->chance ){
if ( rnd_chance<uint16>(option->chance, 10000) ){
apply_sub( item.option[i], option );
}
}

View File

@ -2029,6 +2029,7 @@ enum e_random_item_group {
IG_DUN_VOUCHER_BOX1,
IG_DUN_VOUCHER_BOX2,
IG_BLUEBOXOFQUESTIONS,
IG_ENCHANT_STONE_BOX33,
IG_MAX,
};

View File

@ -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<int16>(1, mapdata->xs - 1);
*y = (ry >= 0) ? rnd_value(by - ry, by + ry) : rnd_value<int16>(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);
@ -2125,9 +2121,10 @@ int map_quit(map_session_data *sd) {
for (i = 0; i < EQI_MAX; i++) {
if (sd->equip_index[i] >= 0)
if (pc_isequip(sd,sd->equip_index[i]))
if( pc_isequip( sd, sd->equip_index[i] ) != ITEM_EQUIP_ACK_OK ){
pc_unequipitem(sd,sd->equip_index[i],2);
}
}
// Return loot to owner
if( sd->pd ) pet_lootitem_drop(sd->pd, sd);
@ -3089,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<directions>(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];
@ -5180,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)

View File

@ -365,6 +365,7 @@ enum e_race2 : uint8{
RC2_EP172BATH,
RC2_ILLUSION_TURTLE,
RC2_RACHEL_SANCTUARY,
RC2_ILLUSION_LUANDA,
RC2_MAX
};

View File

@ -421,7 +421,7 @@ bool mercenary_dead(s_mercenary_data *md) {
void mercenary_killbonus(s_mercenary_data *md) {
std::vector<sc_type> 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);
}
/**

View File

@ -5194,7 +5194,7 @@ static int mob_read_sqldb(void)
for( uint8 fi = 0; fi < ARRAYLENGTH(mob_db_name); ++fi ) {
// retrieve all rows from the mob database
if( SQL_ERROR == Sql_Query(mmysql_handle, "SELECT `id`,`name_aegis`,`name_english`,`name_japanese`,`level`,`hp`,`sp`,`base_exp`,`job_exp`,`mvp_exp`,`attack`,`attack2`,`defense`,`magic_defense`,`str`,`agi`,`vit`,`int`,`dex`,`luk`,`attack_range`,`skill_range`,`chase_range`,`size`,`race`,"
"`racegroup_goblin`,`racegroup_kobold`,`racegroup_orc`,`racegroup_golem`,`racegroup_guardian`,`racegroup_ninja`,`racegroup_gvg`,`racegroup_battlefield`,`racegroup_treasure`,`racegroup_biolab`,`racegroup_manuk`,`racegroup_splendide`,`racegroup_scaraba`,`racegroup_ogh_atk_def`,`racegroup_ogh_hidden`,`racegroup_bio5_swordman_thief`,`racegroup_bio5_acolyte_merchant`,`racegroup_bio5_mage_archer`,`racegroup_bio5_mvp`,`racegroup_clocktower`,`racegroup_thanatos`,`racegroup_faceworm`,`racegroup_hearthunter`,`racegroup_rockridge`,`racegroup_werner_lab`,`racegroup_temple_demon`,`racegroup_illusion_vampire`,`racegroup_malangdo`,`racegroup_ep172alpha`,`racegroup_ep172beta`,`racegroup_ep172bath`,`racegroup_illusion_turtle`,`racegroup_rachel_sanctuary`,"
"`racegroup_goblin`,`racegroup_kobold`,`racegroup_orc`,`racegroup_golem`,`racegroup_guardian`,`racegroup_ninja`,`racegroup_gvg`,`racegroup_battlefield`,`racegroup_treasure`,`racegroup_biolab`,`racegroup_manuk`,`racegroup_splendide`,`racegroup_scaraba`,`racegroup_ogh_atk_def`,`racegroup_ogh_hidden`,`racegroup_bio5_swordman_thief`,`racegroup_bio5_acolyte_merchant`,`racegroup_bio5_mage_archer`,`racegroup_bio5_mvp`,`racegroup_clocktower`,`racegroup_thanatos`,`racegroup_faceworm`,`racegroup_hearthunter`,`racegroup_rockridge`,`racegroup_werner_lab`,`racegroup_temple_demon`,`racegroup_illusion_vampire`,`racegroup_malangdo`,`racegroup_ep172alpha`,`racegroup_ep172beta`,`racegroup_ep172bath`,`racegroup_illusion_turtle`,`racegroup_rachel_sanctuary`,`racegroup_illusion_luanda`,"
"`element`,`element_level`,`walk_speed`,`attack_delay`,`attack_motion`,`damage_motion`,`damage_taken`,`ai`,`class`,"
"`mode_canmove`,`mode_looter`,`mode_aggressive`,`mode_assist`,`mode_castsensoridle`,`mode_norandomwalk`,`mode_nocast`,`mode_canattack`,`mode_castsensorchase`,`mode_changechase`,`mode_angry`,`mode_changetargetmelee`,`mode_changetargetchase`,`mode_targetweak`,`mode_randomtarget`,`mode_ignoremelee`,`mode_ignoremagic`,`mode_ignoreranged`,`mode_mvp`,`mode_ignoremisc`,`mode_knockbackimmune`,`mode_teleportblock`,`mode_fixeditemdrop`,`mode_detector`,`mode_statusimmune`,`mode_skillimmune`,"
"`mvpdrop1_item`,`mvpdrop1_rate`,`mvpdrop1_option`,`mvpdrop1_index`,`mvpdrop2_item`,`mvpdrop2_rate`,`mvpdrop2_option`,`mvpdrop2_index`,`mvpdrop3_item`,`mvpdrop3_rate`,`mvpdrop3_option`,`mvpdrop3_index`,"

View File

@ -475,6 +475,12 @@ struct PACKET_ZC_ACK_SE_CASH_ITEM_LIST2{
struct PACKET_ZC_ACK_SE_CASH_ITEM_LIST2_sub items[];
} __attribute__((packed));
struct PACKET_CZ_REQ_MERGE_ITEM{
int16 packetType;
int16 packetLength;
uint16 indices[];
} __attribute__((packed));
// NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
#if !defined( sun ) && ( !defined( __NETBSD__ ) || __NetBSD_Version__ >= 600000000 )
#pragma pack( pop )
@ -516,7 +522,8 @@ DEFINE_PACKET_HEADER(CZ_REQ_SE_CASH_TAB_CODE, 0x846)
DEFINE_PACKET_HEADER(ZC_ACK_SE_CASH_ITEM_LIST2, 0x8c0)
DEFINE_PACKET_HEADER(ZC_ACK_SCHEDULER_CASHITEM, 0x8ca)
DEFINE_PACKET_HEADER(ZC_CLEAR_DIALOG, 0x8d6)
DEFINE_PACKET_HEADER(ZC_ENTRY_QUEUE_INIT, 0x90e);
DEFINE_PACKET_HEADER(ZC_ENTRY_QUEUE_INIT, 0x90e)
DEFINE_PACKET_HEADER(CZ_REQ_MERGE_ITEM, 0x96e)
DEFINE_PACKET_HEADER(ZC_BANKING_CHECK, 0x9a6)
DEFINE_PACKET_HEADER(ZC_ACK_BANKING_DEPOSIT, 0x9a8)
DEFINE_PACKET_HEADER(ZC_ACK_BANKING_WITHDRAW, 0x9aa)

View File

@ -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];

View File

@ -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;

View File

@ -6567,17 +6567,17 @@ int pc_cartitem_amount(map_session_data* sd, int idx, int amount)
/*==========================================
* Retrieve an item at index idx from cart.
*------------------------------------------*/
void pc_getitemfromcart(map_session_data *sd,int idx,int amount)
bool pc_getitemfromcart(map_session_data *sd,int idx,int amount)
{
nullpo_retv(sd);
nullpo_retr(1, sd);
if (idx < 0 || idx >= MAX_CART) //Invalid index check [Skotlex]
return;
return false;
struct item *item_data=&sd->cart.u.items_cart[idx];
if (item_data->nameid == 0 || amount < 1 || item_data->amount < amount || sd->state.vending || sd->state.prevend)
return;
return false;
enum e_additem_result flag = pc_additem(sd, item_data, amount, LOG_TYPE_NONE);
@ -6588,6 +6588,7 @@ void pc_getitemfromcart(map_session_data *sd,int idx,int amount)
clif_additem(sd, idx, amount, flag);
clif_cart_additem(sd, idx, amount);
}
return true;
}
/*==========================================
@ -6840,9 +6841,10 @@ enum e_setpos pc_setpos(map_session_data* sd, unsigned short mapindex, int x, in
}
for(int i = 0; i < EQI_MAX; i++ ) {
if( sd->equip_index[i] >= 0 )
if( pc_isequip(sd,sd->equip_index[i]) )
if( pc_isequip( sd, sd->equip_index[i] ) != ITEM_EQUIP_ACK_OK ){
pc_unequipitem(sd,sd->equip_index[i],2);
}
}
if (battle_config.clear_unit_onwarp&BL_PC)
skill_clear_unitgroup(&sd->bl);
if( battle_config.loose_ap_on_map && mapdata_flag_vs( mapdata ) ){
@ -9147,9 +9149,10 @@ int pc_resetlvl(map_session_data* sd,int type)
for(i=0;i<EQI_MAX;i++) { // unequip items that can't be equipped by base 1 [Valaris]
if(sd->equip_index[i] >= 0)
if(pc_isequip(sd,sd->equip_index[i]))
if( pc_isequip( sd, sd->equip_index[i] ) != ITEM_EQUIP_ACK_OK ){
pc_unequipitem(sd,sd->equip_index[i],2);
}
}
if ((type == 1 || type == 2 || type == 3) && sd->status.party_id)
party_send_levelup(sd);
@ -10783,9 +10786,10 @@ bool pc_jobchange(map_session_data *sd,int job, char upper)
for(i=0;i<EQI_MAX;i++) {
if(sd->equip_index[i] >= 0)
if(pc_isequip(sd,sd->equip_index[i]))
if( pc_isequip( sd, sd->equip_index[i] ) != ITEM_EQUIP_ACK_OK ){
pc_unequipitem(sd,sd->equip_index[i],2); // unequip invalid item for class
}
}
//Change look, if disguised, you need to undisguise
//to correctly calculate new job sprite without
@ -11810,7 +11814,6 @@ bool pc_equipitem(map_session_data *sd,short n,int req_pos,bool equipswitch)
{
int i, pos, flag = 0, iflag;
struct item_data *id;
uint8 res = ITEM_EQUIP_ACK_OK;
short* equip_index;
nullpo_retr(false,sd);
@ -11840,7 +11843,9 @@ bool pc_equipitem(map_session_data *sd,short n,int req_pos,bool equipswitch)
if(battle_config.battle_log && !equipswitch)
ShowInfo("equip %u (%d) %x:%x\n",sd->inventory.u.items_inventory[n].nameid,n,id?id->equip:0,req_pos);
if((res = pc_isequip(sd,n))) {
uint8 res = pc_isequip( sd, n );
if( res != ITEM_EQUIP_ACK_OK ){
if( equipswitch ){
clif_equipswitch_add( sd, n, req_pos, res );
}else{

View File

@ -1438,7 +1438,7 @@ int pc_getcash( map_session_data *sd, int cash, int points, e_log_pick_type type
enum e_additem_result pc_cart_additem(map_session_data *sd,struct item *item_data,int amount,e_log_pick_type log_type);
void pc_cart_delitem(map_session_data *sd,int n,int amount,int type,e_log_pick_type log_type);
void pc_putitemtocart(map_session_data *sd,int idx,int amount);
void pc_getitemfromcart(map_session_data *sd,int idx,int amount);
bool pc_getitemfromcart(map_session_data *sd,int idx,int amount);
int pc_cartitem_amount(map_session_data *sd,int idx,int amount);
bool pc_takeitem(map_session_data *sd,struct flooritem_data *fitem);

View File

@ -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<uint16>(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;
}

View File

@ -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<uint16>(it->rate, 10000))
continue; // TODO: Should this be affected by server rates?
if (!item_db.exists(it->nameid))
continue;

View File

@ -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<uint16>(MER_EIRA, MER_ELEANOR);
if( sd->hd->homunculus.vaporize == HOM_ST_MORPH ) {
int m_class = hom_class2mapid(sd->hd->homunculus.class_);
@ -27016,6 +27016,41 @@ BUILDIN_FUNC(has_autoloot) {
return SCRIPT_CMD_SUCCESS;
}
// ===================================
// *autoloot({<rate>{, <char_id>}});
// This command sets the rate of autoloot.
// If no rate is provided and the user has autoloot disabled it will default to 10000 = 100% (enabled) or
// if the user has autoloot enabled it will default to 0 = 0% (disabled).
// Returns true on success and false on failure.
// ===================================
BUILDIN_FUNC(autoloot) {
map_session_data *sd = nullptr;
if (!script_charid2sd(3, sd)) {
script_pushint(st, false);
return SCRIPT_CMD_FAILURE;
}
int rate;
if (script_hasdata(st, 2)) {
rate = script_getnum(st, 2);
if (rate < 0 || rate > 10000) {
ShowWarning("buildin_autoloot: Invalid rate value %d, should be between 0 ~ 10000.\n", rate);
script_pushint(st, false);
return SCRIPT_CMD_FAILURE;
}
} else {
rate = (sd->state.autoloot > 0 ? 0 : 10000);
}
sd->state.autoloot = rate;
script_pushint(st, true);
return SCRIPT_CMD_SUCCESS;
}
BUILDIN_FUNC(opentips){
#if PACKETVER < 20171122
ShowError( "buildin_opentips: This command requires PACKETVER 20171122 or newer.\n" );
@ -27789,6 +27824,7 @@ struct script_function buildin_func[] = {
BUILDIN_DEF(isdead, "?"),
BUILDIN_DEF(macro_detector, "?"),
BUILDIN_DEF(has_autoloot,"?"),
BUILDIN_DEF(autoloot,"??"),
BUILDIN_DEF(opentips, "i?"),
#include <custom/script_def.inc>

View File

@ -2088,6 +2088,40 @@ enum e_hat_effects : int16{
HAT_EF_ALICE_TEA,
HAT_EF_C_DARK_LORD_CLOAK,
HAT_EF_C_SAKURA_FUBUKI,
HAT_EF_C_DARK_LORD_MANTEAU,
HAT_EF_DECORATION_OF_MUSIC,
HAT_EF_2023RTC_S_ROBE1,
HAT_EF_2023RTC_S_ROBE2,
HAT_EF_2023RTC_S_ROBE3,
HAT_EF_C_CONSECRATE_F_AUREOLA,
HAT_EF_C_BULB_WREATH,
HAT_EF_MD_HOL_BARRIER1,
HAT_EF_MD_HOL_BARRIER2,
HAT_EF_MD_HOL_BARRIER3,
HAT_EF_MD_HOL_BARRIER4,
HAT_EF_MD_HOL_BARRIER5,
HAT_EF_MD_HOL_BARRIER6,
HAT_EF_MD_HOL_BARRIER7,
HAT_EF_MD_HOL_BARRIER8,
HAT_EF_MD_HOL_BARRIER9,
HAT_EF_MD_HOL_BARRIER10,
HAT_EF_MD_HOL_BARRIER11,
HAT_EF_MD_HOL_BARRIER12,
HAT_EF_MD_HOL_BARRIER13,
HAT_EF_MD_HOL_BARRIER14,
HAT_EF_MD_HOL_BARRIER15,
HAT_EF_MD_HOL_BARRIER16,
HAT_EF_MD_HOL_BARRIER17,
HAT_EF_MD_HOL_BARRIER18,
HAT_EF_MD_HOL_BARRIER19,
HAT_EF_MD_HOL_BARRIER20,
HAT_EF_C_FLUTTERING_HAZE,
HAT_EF_EFST_CINNAMON,
HAT_EF_AUTUMN_FULL_MOON,
HAT_EF_NIFLHEIM_NIGHT_SKY,
HAT_EF_C_ROS2023_CAPE_1,
HAT_EF_C_ROS2023_CAPE_2,
HAT_EF_C_15TH_NOV_HELMET,
HAT_EF_MAX
};

View File

@ -964,6 +964,7 @@
export_constant2("Eff_Heat",SC_BURNT);
export_constant2("Eff_Deepsleep",SC_DEEPSLEEP);
export_constant2("Eff_WhiteImprison",SC_WHITEIMPRISON);
export_constant2("Eff_Hallucination",SC_HALLUCINATION);
export_constant2("SC_ALL",SC_NONE);
@ -4223,6 +4224,7 @@
export_constant(RC2_EP172BATH);
export_constant(RC2_ILLUSION_TURTLE);
export_constant(RC2_RACHEL_SANCTUARY);
export_constant(RC2_ILLUSION_LUANDA);
export_constant(RC2_MAX);
/* monster ai */
@ -6973,6 +6975,7 @@
export_constant(IG_DUN_VOUCHER_BOX1);
export_constant(IG_DUN_VOUCHER_BOX2);
export_constant(IG_BLUEBOXOFQUESTIONS);
export_constant(IG_ENCHANT_STONE_BOX33);
/* unit stop walking */
export_constant(USW_NONE);
@ -9581,6 +9584,40 @@
export_constant(HAT_EF_ALICE_TEA);
export_constant(HAT_EF_C_DARK_LORD_CLOAK);
export_constant(HAT_EF_C_SAKURA_FUBUKI);
export_constant(HAT_EF_C_DARK_LORD_MANTEAU);
export_constant(HAT_EF_DECORATION_OF_MUSIC);
export_constant(HAT_EF_2023RTC_S_ROBE1);
export_constant(HAT_EF_2023RTC_S_ROBE2);
export_constant(HAT_EF_2023RTC_S_ROBE3);
export_constant(HAT_EF_C_CONSECRATE_F_AUREOLA);
export_constant(HAT_EF_C_BULB_WREATH);
export_constant(HAT_EF_MD_HOL_BARRIER1);
export_constant(HAT_EF_MD_HOL_BARRIER2);
export_constant(HAT_EF_MD_HOL_BARRIER3);
export_constant(HAT_EF_MD_HOL_BARRIER4);
export_constant(HAT_EF_MD_HOL_BARRIER5);
export_constant(HAT_EF_MD_HOL_BARRIER6);
export_constant(HAT_EF_MD_HOL_BARRIER7);
export_constant(HAT_EF_MD_HOL_BARRIER8);
export_constant(HAT_EF_MD_HOL_BARRIER9);
export_constant(HAT_EF_MD_HOL_BARRIER10);
export_constant(HAT_EF_MD_HOL_BARRIER11);
export_constant(HAT_EF_MD_HOL_BARRIER12);
export_constant(HAT_EF_MD_HOL_BARRIER13);
export_constant(HAT_EF_MD_HOL_BARRIER14);
export_constant(HAT_EF_MD_HOL_BARRIER15);
export_constant(HAT_EF_MD_HOL_BARRIER16);
export_constant(HAT_EF_MD_HOL_BARRIER17);
export_constant(HAT_EF_MD_HOL_BARRIER18);
export_constant(HAT_EF_MD_HOL_BARRIER19);
export_constant(HAT_EF_MD_HOL_BARRIER20);
export_constant(HAT_EF_C_FLUTTERING_HAZE);
export_constant(HAT_EF_EFST_CINNAMON);
export_constant(HAT_EF_AUTUMN_FULL_MOON);
export_constant(HAT_EF_NIFLHEIM_NIGHT_SKY);
export_constant(HAT_EF_C_ROS2023_CAPE_1);
export_constant(HAT_EF_C_ROS2023_CAPE_2);
export_constant(HAT_EF_C_15TH_NOV_HELMET);
/* pet catch */
export_constant(PET_CATCH_UNIVERSAL);

View File

@ -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<uint16>(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<uint16>( 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<uint16>( 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<uint16>( 1, autospl_skill_lv );
int autospl_rate = it.rate;

View File

@ -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<int>(DIR_NORTH, DIR_NORTHEAST); // Pick a Random Dir
dx = -dirx[k] * 2;
dy = -diry[k] * 2;