Merge branch 'master' into hotfix/issue6912

# Conflicts:
#	conf/battle/feature.conf
#	src/map/packets.hpp
This commit is contained in:
Lemongrass3110 2022-11-20 19:10:31 +01:00
commit 70b54081da
52 changed files with 2847 additions and 644 deletions

View File

@ -20,8 +20,7 @@ print_start() {
get_status(){
PIDFILE=.$1.pid
if [ -e ${PIDFILE} ]; then
ISRUN=$(ps ax | grep $(cat ${PIDFILE}) | grep $1)
PSRUN=$(echo "$ISRUN" | awk '{ print $1 }')
PSRUN=$(pgrep -F ${PIDFILE})
fi
#return ${PSRUN} #seems to cause an issue for some os
}
@ -40,7 +39,7 @@ start_serv(){
mkfifo "$FIFO"; tee "$LOGRUN" < "$FIFO" & "./$1" > "$FIFO" 2>&1 & PID=$!
#"./$1" > >(tee "$LOGRUN") 2>&1 & PID=$! #bash only
echo "$PID" > .$1.pid
echo "Server '$1' started at `date +"%m-%d-%H:%M-%S"`" | tee ${LOGFILE}
echo "Server '$1' started at $(date +"%m-%d-%H:%M-%S")" | tee ${LOGFILE}
else
echo "Cannot start '$1', because it is already running p${PSRUN}" | tee ${LOGFILE}
fi
@ -48,7 +47,7 @@ start_serv(){
if [ -z ${PSRUN} ]; then
./$1&
echo "$!" > .$1.pid
echo "Server '$1' started at `date +"%m-%d-%H:%M-%S"`"
echo "Server '$1' started at $(date +"%m-%d-%H:%M-%S")"
else
echo "Cannot start '$1', because it is already running p${PSRUN}"
fi
@ -67,15 +66,15 @@ watch_serv(){
LOGRUN="$LOG_DIR/$i.log"
FIFO=$i"_fifo"
get_status $i
get_status ${i}
#echo "Echo id of $i is ${PSRUN}"
if [ -z ${PSRUN} ]; then
count=$((count+1))
#echo "fifo=$FIFO"
echo "server '$i' is down"
echo "server '$i' is down" >> ${LOGFILE}
echo "restarting server at time at `date +"%m-%d-%H:%M-%S"`"
echo "restarting server at time at `date +"%m-%d-%H:%M-%S"`" >> ${LOGFILE}
echo "restarting server at time at $(date +"%m-%d-%H:%M-%S")"
echo "restarting server at time at $(date +"%m-%d-%H:%M-%S")" >> ${LOGFILE}
if [ -e $FIFO ]; then rm $FIFO; fi
mkfifo "$FIFO"; tee "$LOGRUN" < "$FIFO" & "./$i" > "$FIFO" 2>&1 & PID=$!
echo "$PID" > .$i.pid
@ -155,7 +154,7 @@ case $1 in
done
;;
'restart')
restart
restart "$@"
;;
'status')
for i in ${L_SRV} ${C_SRV} ${M_SRV} ${W_SRV}
@ -181,7 +180,7 @@ case $1 in
'start')
echo "syntax: 'start {--enlog}'"
echo "This option will start the servers"
echo "--enlog will write all terminal output into a log/$servname.log file"
echo "--enlog will write all terminal output into a log/\$servname.log file"
;;
'stop')
echo "This option will shut the servers down"
@ -205,11 +204,11 @@ case $1 in
;;
'val_runonce')
echo "syntax: 'val_runonce'"
echo "This option will run valgrin with run-once to check the servers"
echo "This option will run valgrind with run-once to check the servers"
;;
'valchk')
echo "syntax: 'valchk'"
echo "This option will run valgrin with the servers"
echo "This option will run valgrind with the servers"
;;
*)
echo "Please specify a command you would like more info on { start | stop | restart | status | watch }"

View File

@ -1016,6 +1016,9 @@ Body:
- Command: enchantgradeui
Help: |
Opens the enchantgrade UI.
- Command: roulette
Help: |
Opens the roulette UI.
Footer:
Imports:

View File

@ -136,6 +136,13 @@ feature.dynamicnpc_rangey: 2
// Default: no
feature.dynamicnpc_direction: no
// Itemlink System on informational related commands (Note 1)
// Generates <ITEML> string for an item and can be used for npctalk, message,
// dispbottom, and broadcast commands. The result is clickable-item name just
// like from SHIFT+Click from player's inventory/cart/equipment window.
// Requires: 2010-00-00RagexeRE or later
feature.itemlink: on
// Enable the Gold PC timer? (Note 1)
// Default: yes
feature.goldpc_active: yes

View File

@ -121,7 +121,8 @@ start_point_doram: lasa_fild01,48,297
// Format: <id>,<amount>,<position>{:<id>,<amount>,<position>...}
// To auto-equip an item, include the position where it will be equipped; otherwise, use zero.
// NOTE: For Doram, this requires client 20151001 or newer.
start_items: 1201,1,2:2301,1,16
start_items: 1201,1,2:2301,1,16:23484,1,0
start_items_pre: 1201,1,2:2301,1,16
start_items_doram: 1681,1,2:2301,1,16
// Starting zeny for new characters

View File

@ -1784,6 +1784,12 @@ Body:
Rewards:
TitleId: 1034
Score: 10
- Id: 130005 # TODO (Terra Gloria: give achievement when player visit the coronation ceremony)
Group: Chatting
Name: Who made the king
Rewards:
TitleID: 1046
Score: 10
- Id: 170000
Group: Chatting
Name: Song chamber is not an accident
@ -2037,30 +2043,38 @@ Body:
Name: Reborn in Valhalla!
Condition: " Class == JOB_NOVICE_HIGH "
Rewards:
# Item: Adventurer_Box_1
Item: Adventurer_Box_1
Script: " specialeffect2 EF_INCAGILITY; sc_start SC_INCREASEAGI,30000,10; "
Score: 10
- Id: 200032
Group: Goal_Level
Name: The start of another adventure!
Condition: " BaseLevel == 100 "
#Rewards:
# Item: Rebeginer_Box_100
Rewards:
Item: Rebeginer_Box_100
Score: 10
- Id: 200033
Group: Goal_Level
Name: With a new mind!(1)
Condition: " BaseLevel == 170 && (Class >= JOB_RUNE_KNIGHT && Class <= JOB_GUILLOTINE_CROSS_T) "
#Rewards:
# Item: Costume_Ticket
Rewards:
Item: Costume_Ticket
Score: 50
- Id: 200034
Group: Goal_Level
Name: With a new mind!(2)
Condition: " BaseLevel == 170 && (Class >= JOB_ROYAL_GUARD && Class <= JOB_SHADOW_CHASER_T) "
#Rewards:
# Item: Costume_Ticket
Rewards:
Item: Costume_Ticket
Score: 50
- Id: 200035
Group: Goal_Level
Name: Level 200 achieved!
Condition: " BaseLevel == 200 "
Rewards:
Item: C_Magestic_Goat2
Script: " specialeffect2 EF_BLESSING; sc_start SC_BLESSING,30000,10; "
Score: 100
- Id: 220000
Group: Chatting_Create
Name: Community begin

View File

@ -30333,7 +30333,7 @@ Body:
- G_Strings # 2339
- Combo:
- Etran_Shirt_TW # 20910
- G_Strings # 2371
- G_Strings_ # 2371
Script: |
.@r = getequiprefinerycnt(EQI_ARMOR);
bonus bInt,15;

View File

@ -21172,8 +21172,7 @@ Body:
SoulLinker: true
Wizard: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 3
EquipLevelMin: 100
Refineable: true
@ -21401,8 +21400,7 @@ Body:
All_Third: true
Fourth: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 3
EquipLevelMin: 100
Refineable: true
@ -55510,7 +55508,7 @@ Body:
Script: |
bonus bMdef,5;
.@def = 10;
if (getpetinfo(PETINFO_ID) == 9026) {
if (getpetinfo(PETINFO_EGGID) == 9026) {
.@def += 5;
if (getpetinfo(PETINFO_INTIMATE) >= PET_INTIMATE_CORDIAL) {
.@def += 5;
@ -60231,8 +60229,7 @@ Body:
Gunslinger: true
Rebellion: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 3
EquipLevelMin: 100
Refineable: true
@ -60263,8 +60260,7 @@ Body:
Gunslinger: true
Rebellion: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 3
EquipLevelMin: 100
Refineable: true
@ -60372,8 +60368,7 @@ Body:
Jobs:
Rebellion: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 3
EquipLevelMin: 100
Trade:
@ -62168,8 +62163,7 @@ Body:
KagerouOboro: true
Ninja: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 3
EquipLevelMin: 100
Refineable: true
@ -62283,8 +62277,7 @@ Body:
KagerouOboro: true
Ninja: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 3
EquipLevelMin: 100
Refineable: true
@ -62403,8 +62396,7 @@ Body:
Jobs:
KagerouOboro: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 3
EquipLevelMin: 100
Trade:
@ -73200,8 +73192,7 @@ Body:
BardDancer: true
Hunter: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 3
EquipLevelMin: 100
Refineable: true
@ -73354,8 +73345,7 @@ Body:
All_Third: true
Fourth: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 3
EquipLevelMin: 100
Refineable: true
@ -73388,8 +73378,7 @@ Body:
All_Third: true
Fourth: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 3
EquipLevelMin: 100
Refineable: true
@ -73556,8 +73545,7 @@ Body:
All_Third: true
Fourth: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 3
EquipLevelMin: 100
Trade:
@ -73588,8 +73576,7 @@ Body:
All_Third: true
Fourth: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 3
EquipLevelMin: 100
Trade:
@ -73816,8 +73803,7 @@ Body:
All_Third: true
Fourth: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 4
EquipLevelMin: 99
Trade:
@ -73855,8 +73841,7 @@ Body:
All_Third: true
Fourth: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 4
EquipLevelMin: 99
Trade:
@ -81479,7 +81464,7 @@ Body:
bonus bMatkRate,7;
else
bonus bMatkRate,5;
if (getpetinfo(PETINFO_ID) == 9023) {
if (getpetinfo(PETINFO_EGGID) == 9023) {
if (getpetinfo(PETINFO_INTIMATE) >= PET_INTIMATE_LOYAL)
bonus bDelayRate,-5;
else
@ -84173,9 +84158,13 @@ Body:
bonus bSPGainValue,50;
bonus bLongSPGainValue,50;
bonus bMagicSPGainValue,50;
if (getpetinfo(PETINFO_ID) == 9055) {
bonus2 bHPRegenRate,(getpetinfo(PETINFO_INTIMATE) >= PET_INTIMATE_LOYAL ? 1000 : 500),5000;
bonus2 bSPRegenRate,(getpetinfo(PETINFO_INTIMATE) >= PET_INTIMATE_LOYAL ? 40 : 20),5000;
if (getpetinfo(PETINFO_EGGID) == 9055) {
if (getpetinfo(PETINFO_INTIMATE) >= PET_INTIMATE_LOYAL)
.@factor = 2;
else
.@factor = 1;
bonus2 bHPRegenRate,(.@factor*500),5000;
bonus2 bSPRegenRate,(.@factor*20),5000;
}
UnEquipScript: |
heal -5000,-500;
@ -102634,8 +102623,7 @@ Body:
Knight: true
Swordman: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 3
EquipLevelMin: 100
Refineable: true
@ -102757,8 +102745,7 @@ Body:
All_Third: true
Fourth: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 3
EquipLevelMin: 100
Refineable: true
@ -102817,8 +102804,7 @@ Body:
All_Third: true
Fourth: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 3
EquipLevelMin: 100
Trade:
@ -102974,8 +102960,7 @@ Body:
All_Third: true
Fourth: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 4
EquipLevelMin: 99
Trade:
@ -119016,8 +119001,7 @@ Body:
Knight: true
Swordman: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 3
EquipLevelMin: 100
Refineable: true
@ -119167,8 +119151,7 @@ Body:
All_Third: true
Fourth: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 3
EquipLevelMin: 100
Trade:
@ -120946,8 +120929,7 @@ Body:
Jobs:
Assassin: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 3
EquipLevelMin: 100
Refineable: true
@ -121090,8 +121072,7 @@ Body:
All_Third: true
Fourth: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 3
EquipLevelMin: 100
Refineable: true
@ -121149,8 +121130,7 @@ Body:
All_Third: true
Fourth: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 3
EquipLevelMin: 100
Trade:
@ -121279,8 +121259,7 @@ Body:
All_Third: true
Fourth: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 4
EquipLevelMin: 99
Trade:
@ -121731,8 +121710,7 @@ Body:
Merchant: true
Swordman: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 3
EquipLevelMin: 100
Refineable: true
@ -121893,8 +121871,7 @@ Body:
All_Third: true
Fourth: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 3
EquipLevelMin: 100
Refineable: true
@ -122115,8 +122092,7 @@ Body:
All_Third: true
Fourth: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 4
EquipLevelMin: 99
Trade:
@ -122383,8 +122359,7 @@ Body:
Gunslinger: true
Rebellion: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 3
EquipLevelMin: 100
Refineable: true
@ -122417,8 +122392,7 @@ Body:
Gunslinger: true
Rebellion: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 3
EquipLevelMin: 100
Refineable: true
@ -122452,8 +122426,7 @@ Body:
Gunslinger: true
Rebellion: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 3
EquipLevelMin: 100
Refineable: true
@ -122484,8 +122457,7 @@ Body:
Gunslinger: true
Rebellion: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 3
EquipLevelMin: 100
Refineable: true
@ -143797,30 +143769,34 @@ Body:
Script: |
bonus2 bAddSize,Size_All,10;
bonus2 bMagicAddSize,Size_All,10;
if (getpetinfo(PETINFO_ID) == 9112)
switch( getpetinfo(PETINFO_EGGID) ) {
case 9112: // Moonlight_Egg
bonus2 bHPVanishRate,40,4;
if (getpetinfo(PETINFO_ID) == 9088) {
break;
case 9088: // Angeling_Egg
bonus bBaseAtk,readparam(bLuk);
bonus bMatk,readparam(bLuk);
bonus2 bExpAddClass,Class_All,5;
}
if (getpetinfo(PETINFO_ID) == 9096) {
break;
case 9096: // Cat_O_Nine_Tail_Egg
bonus2 bAddRace,RC_Demon,30;
bonus2 bMagicAddRace,RC_Demon,30;
bonus2 bSubRace,RC_Demon,5;
}
if (getpetinfo(PETINFO_ID) == 9087) {
break;
case 9087: // High_Orc_Egg
bonus2 bAddRace,RC_Brute,30;
bonus2 bMagicAddRace,RC_Brute,30;
bonus2 bSubRace,RC_Brute,5;
}
if (getpetinfo(PETINFO_ID) == 9069) {
break;
case 9069: // Mastering_Egg
bonus2 bAddRace,RC_Plant,30;
bonus2 bMagicAddRace,RC_Plant,30;
bonus2 bSubRace,RC_Plant,5;
}
if (getpetinfo(PETINFO_ID) == 9106)
break;
case 9106: // Metaller_Egg
bonus3 bAutoSpell,"WM_METALICSOUND",5,150;
break;
}
- Id: 410028
AegisName: Wonder_Egg_Basket_
Name: Wonder Egg Basket
@ -143834,23 +143810,39 @@ Body:
EquipLevelMin: 100
Script: |
bonus bAspdRate,10;
if (getpetinfo(PETINFO_ID) == 9109 || getpetinfo(PETINFO_ID) == 9112 || getpetinfo(PETINFO_ID) == 9115 || getpetinfo(PETINFO_ID) == 9121) {
switch( getpetinfo(PETINFO_EGGID) ) {
case 9109: // Sweet_Drops_Egg
case 9112: // Moonlight_Egg
case 9115: // Bacsojin_Egg2
case 9121: // Orc_Hero_Egg_
case 9126: // Kiel_Egg
case 9136: // Eddga_Egg
bonus bBaseAtk,200;
bonus bMatk,200;
bonus bAllStats,10;
}
/*Todo Itemid 9126 9136*/
if (getpetinfo(PETINFO_ID) == 9088 || getpetinfo(PETINFO_ID) == 9108 || getpetinfo(PETINFO_ID) == 9113) {
break;
case 9088: // Angeling_Egg
case 9108: // Xm_Teddybear_Egg
case 9113: // Roost_Of_Skelion
bonus bBaseAtk,200;
bonus bMatk,200;
bonus2 bAddSize,Size_All,10;
bonus2 bMagicAddSize,Size_All,10;
}
if (getpetinfo(PETINFO_ID) == 9069 || getpetinfo(PETINFO_ID) == 9087 || getpetinfo(PETINFO_ID) == 9096 || getpetinfo(PETINFO_ID) == 9106 || getpetinfo(PETINFO_ID) == 9117 || getpetinfo(PETINFO_ID) == 9118 || getpetinfo(PETINFO_ID) == 9119 || getpetinfo(PETINFO_ID) == 9120 || getpetinfo(PETINFO_ID) == 9124) {
break;
case 9069: // Mastering_Egg
case 9087: // High_Orc_Egg
case 9096: // Cat_O_Nine_Tail_Egg
case 9106: // Metaller_Egg
case 9117: // Contaminated_Wanderer_Egg
case 9118: // Aliot_Egg
case 9119: // Alicel_Egg
case 9120: // Aliza_Egg
case 9124: // Ep17_2_C_Admin2_Egg
bonus bBaseAtk,200;
bonus bMatk,200;
bonus bDef,150;
bonus bMdef,15;
break;
}
- Id: 410029
AegisName: C_Wonder_Egg_Basket
@ -174531,8 +174523,7 @@ Body:
All_Third: true
Fourth: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 1
# Flags:
# BuyingStore: true
@ -174719,8 +174710,7 @@ Body:
All_Third: true
Fourth: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 4
EquipLevelMin: 100
Refineable: true
@ -175493,8 +175483,7 @@ Body:
All_Third: true
Fourth: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 4
EquipLevelMin: 100
Refineable: true
@ -176425,8 +176414,7 @@ Body:
All_Third: true
Fourth: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 4
EquipLevelMin: 100
Refineable: true
@ -177122,8 +177110,7 @@ Body:
All_Third: true
Fourth: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 4
EquipLevelMin: 100
Refineable: true
@ -177571,8 +177558,7 @@ Body:
All_Third: true
Fourth: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 4
EquipLevelMin: 100
Refineable: true
@ -177620,8 +177606,7 @@ Body:
All_Third: true
Fourth: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 4
EquipLevelMin: 100
Refineable: true
@ -178694,8 +178679,7 @@ Body:
KagerouOboro: true
Ninja: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 4
EquipLevelMin: 150
Refineable: true
@ -179499,8 +179483,7 @@ Body:
All_Third: true
Fourth: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 1
# Flags:
# BuyingStore: true
@ -179709,8 +179692,7 @@ Body:
All_Third: true
Fourth: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 4
EquipLevelMin: 100
Refineable: true
@ -179755,8 +179737,7 @@ Body:
All_Third: true
Fourth: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 4
EquipLevelMin: 100
Refineable: true
@ -179799,8 +179780,7 @@ Body:
All_Third: true
Fourth: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 4
EquipLevelMin: 100
Refineable: true
@ -179845,8 +179825,7 @@ Body:
All_Third: true
Fourth: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 4
EquipLevelMin: 100
Refineable: true
@ -181316,8 +181295,7 @@ Body:
Gunslinger: true
Rebellion: true
Locations:
Right_Hand: true
Left_Hand: true
Both_Hand: true
WeaponLevel: 1
# Flags:
# BuyingStore: true

View File

@ -3802,6 +3802,34 @@ Body:
Script: |
itemheal rand(50,100),0;
/*TODO*/
- Id: 11614
AegisName: Fresh_Milk
Name: Fresh Milk
Type: Healing
Weight: 30
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoAuction: true
Script: |
itemheal rand(27,37),0;
- Id: 11615
AegisName: Sweet_Potato_
Name: Sweet Potato
Type: Healing
Weight: 20
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoAuction: true
Script: |
itemheal rand(15,23),0;
- Id: 11616
AegisName: Yummy_Meat
Name: Delicious Meat
@ -47350,6 +47378,21 @@ Body:
Script: |
specialeffect2 EF_CLAYMORE;
setmadogear true;
- Id: 23278
AegisName: HelpmeShorty
Name: Help Me Shorty
Type: Delayconsume
Trade:
NoDrop: true
NoTrade: true
NoSell: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
duplicate_dynamic("Shorty#fgtg01");
- Id: 23280
AegisName: N_Fly_Wing_
Name: Novice Fly Wing
@ -47539,6 +47582,20 @@ Body:
Script: |
input .@megaphone$;
announce strcharinfo(0) + ": " + .@megaphone$,bc_all,0xFF0000;
- Id: 23338
AegisName: Comp_Wing_Of_Fly
Name: Compressed Fly Wing
Type: Delayconsume
Weight: 0
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
itemskill "AL_TELEPORT",1;
- Id: 23360
AegisName: Psychotropic
Name: Psychotropic
@ -47678,6 +47735,397 @@ Body:
Script: |
specialeffect2 EF_POTION_BERSERK;
sc_start SC_INFINITY_DRINK,1800000,0;
- Id: 23484
AegisName: Firstaid_Box_5
Name: First aid Box (5)
Type: Usable
EquipLevelMin: 5
Weight: 0
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
getitem 11518,10;
getitem 11614,20;
getitem 12325,15;
getitem 22542,1;
getitem 23485,1;
- Id: 23485
AegisName: Firstaid_Box_10
Name: First aid Box (10)
Type: Usable
EquipLevelMin: 10
Weight: 0
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
getitem 11518,15;
getitem 11614,40;
getitem 12325,15;
getitem 22542,1;
getitem 23486,1;
- Id: 23486
AegisName: Firstaid_Box_15
Name: First aid Box (15)
Type: Usable
EquipLevelMin: 15
Weight: 0
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
getitem 11518,20;
getitem 11614,60;
getitem 12325,10;
getitem 22542,2;
getitem 23487,1;
- Id: 23487
AegisName: Firstaid_Box_20
Name: First aid Box (20)
Type: Usable
EquipLevelMin: 20
Weight: 0
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
getitem 11518,15;
getitem 11615,80;
getitem 12325,10;
getitem 22542,2;
getitem 23488,1;
- Id: 23488
AegisName: Firstaid_Box_25
Name: First aid Box (25)
Type: Usable
EquipLevelMin: 25
Weight: 0
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
getitem 11518,20;
getitem 11615,100;
getitem 12325,5;
getitem 22542,3;
getitem 23489,1;
- Id: 23489
AegisName: Firstaid_Box_30
Name: First aid Box (30)
Type: Usable
EquipLevelMin: 30
Weight: 0
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
getitem 11518,25;
getitem 11615,120;
getitem 12325,5;
getitem 22542,3;
getitem 23490,1;
- Id: 23490
AegisName: Firstaid_Box_35
Name: First aid Box (35)
Type: Usable
EquipLevelMin: 35
Weight: 0
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
getitem 11572,15;
getitem 22542,3;
getitem 23491,1;
getitem 23503,5;
- Id: 23491
AegisName: Firstaid_Box_40
Name: First aid Box (40)
Type: Usable
EquipLevelMin: 40
Weight: 0
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
getitem 11572,15;
getitem 22544,2;
getitem 23492,1;
getitem 23503,6;
- Id: 23492
AegisName: Firstaid_Box_45
Name: First aid Box (45)
Type: Usable
EquipLevelMin: 45
Weight: 0
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
getitem 11572,20;
getitem 22544,2;
getitem 23493,1;
getitem 23503,7;
- Id: 23493
AegisName: Firstaid_Box_50
Name: First aid Box (50)
Type: Usable
EquipLevelMin: 50
Weight: 0
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
getitem 11572,20;
getitem 22544,2;
getitem 23494,1;
getitem 23504,7;
- Id: 23494
AegisName: Firstaid_Box_55
Name: First aid Box (55)
Type: Usable
EquipLevelMin: 55
Weight: 0
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
getitem 11572,25;
getitem 22544,2;
getitem 23495,1;
getitem 23504,8;
- Id: 23495
AegisName: Firstaid_Box_60
Name: First aid Box (60)
Type: Usable
EquipLevelMin: 60
Weight: 0
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
getitem 11572,25;
getitem 23496,1;
getitem 23504,9;
- Id: 23496
AegisName: Firstaid_Box_65
Name: First aid Box (65)
Type: Usable
EquipLevelMin: 65
Weight: 0
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
getitem 11572,30;
getitem 23497,1;
getitem 23505,5;
- Id: 23497
AegisName: Firstaid_Box_70
Name: First aid Box (70)
Type: Usable
EquipLevelMin: 70
Weight: 0
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
getitem 11572,30;
getitem 23498,1;
getitem 23505,6;
- Id: 23498
AegisName: Firstaid_Box_75
Name: First aid Box (75)
Type: Usable
EquipLevelMin: 75
Weight: 0
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
getitem 11572,35;
getitem 23499,1;
getitem 23505,7;
- Id: 23499
AegisName: Firstaid_Box_80
Name: First aid Box (80)
Type: Usable
EquipLevelMin: 80
Weight: 0
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
getitem 11572,35;
getitem 23500,1;
getitem 23505,8;
- Id: 23500
AegisName: Firstaid_Box_85
Name: First aid Box (85)
Type: Usable
EquipLevelMin: 85
Weight: 0
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
getitem 11572,40;
getitem 22543,2;
getitem 23501,1;
getitem 23506,7;
- Id: 23501
AegisName: Firstaid_Box_90
Name: First aid Box (90)
Type: Usable
EquipLevelMin: 90
Weight: 0
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
getitem 11572,40;
getitem 22543,2;
getitem 23502,1;
getitem 23506,8;
- Id: 23502
AegisName: Firstaid_Box_95
Name: First aid Box (95)
Type: Usable
EquipLevelMin: 95
Weight: 0
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
getitem 11572,45;
getitem 22543,2;
getitem 23506,8;
- Id: 23503
AegisName: Red_Potion_B_20
Name: "[Event] Crate of 20 Red Potions"
Type: Usable
Weight: 0
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
getitem 11570,20;
- Id: 23504
AegisName: Orange_Potion_B_20
Name: "[Event] Crate of 20 Orange Potions"
Type: Usable
Weight: 0
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
getitem 11569,20;
- Id: 23505
AegisName: Yellow_Potion_B_20
Name: "[Event] Crate of 20 Yellow Potions"
@ -47808,6 +48256,132 @@ Body:
Script: |
percentheal 5,0;
sc_start SC_MATKPOTION,600000,3;
- Id: 23575
AegisName: Adventurer_Box_1
Name: Adventurer Box (1)
Type: Usable
Weight: 0
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
getitem 11567,100;
getitem 12265,5;
getitem 22979,5;
getitem 23338,50;
getitem 23576,1;
- Id: 23576
AegisName: Adventurer_Box_15
Name: Adventurer Box (15)
Type: Usable
EquipLevelMin: 15
Weight: 0
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
getitem 11567,150;
getitem 23338,50;
getitem 23577,1;
- Id: 23577
AegisName: Adventurer_Box_30
Name: Adventurer Box (30)
Type: Usable
EquipLevelMin: 30
Weight: 0
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
getitem 23338,50;
getitem 23503,20;
getitem 23578,1;
- Id: 23578
AegisName: Adventurer_Box_45
Name: Adventurer Box (45)
Type: Usable
EquipLevelMin: 45
Weight: 0
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
getitem 23338,50;
getitem 23503,25;
getitem 23579,1;
- Id: 23579
AegisName: Adventurer_Box_60
Name: Adventurer Box (60)
Type: Usable
EquipLevelMin: 60
Weight: 0
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
getitem 23338,50;
getitem 23504,20;
getitem 23580,1;
- Id: 23580
AegisName: Adventurer_Box_75
Name: Adventurer Box (75)
Type: Usable
EquipLevelMin: 75
Weight: 0
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
getitem 23338,50;
getitem 23504,25;
getitem 23581,1;
- Id: 23581
AegisName: Adventurer_Box_90
Name: Adventurer Box (90)
Type: Usable
EquipLevelMin: 90
Weight: 0
Trade:
NoDrop: true
NoTrade: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
Script: |
getitem 23505,20;
getitem 23338,50;
- Id: 23582
AegisName: E_Wing_Of_Fly_3Day_Box
Name: "[Gift] Unlimited Fly Wing 3 Day Box"

View File

@ -9790,6 +9790,17 @@ Body:
- Id: 14687
Title: Mysterious Device
TimeLimit: +1h
- Id: 14688
Title: My name is Shorty
- Id: 14689
Title: Help Shorty
- Id: 14693
Title: To Payon
- Id: 14694
Title: To Prontera Field
- Id: 14695
Title: Cheer up, Sunsammi!
TimeLimit: +30mn
- Id: 14699
Title: Event once a day
TimeLimit: 4h

View File

@ -18,6 +18,7 @@ We want to add our own custom achievement that can be given to a player via an N
#### /db/import/achievement_db.yml
```yml
- Id: 280000
Group: None
Name: Emperio
@ -30,6 +31,7 @@ We want to add our own custom achievement that can be given to a player via an N
Reward:
TitleId: 1036
Score: 50
```
### Instances
@ -38,6 +40,7 @@ We want to add our own customized Housing Instance.
#### /db/import/instance_db.yml
```yml
- Id: 35
Name: Home
IdleTimeOut: 900
@ -48,17 +51,19 @@ We want to add our own customized Housing Instance.
AdditionalMaps:
- Map: 2@home
- Map: 3@home
```
### Mob Alias
---
We want to give a custom mob a Novice player sprite.
We want to make Porings look like Baphomet.
#### /db/import/mob_avail.txt
#### /db/import/mob_avail.yml
// Structure of Database:
// MobID,SpriteID{,Equipment}
3850,0
```yml
- Mob: PORING
Sprite: BAPHOMET
```
### Custom Maps
@ -67,45 +72,71 @@ We want to add our own custom maps. For this we need to add our map names to `im
#### /db/import/map_index.txt
```
1@home 1250
2@home
3@home
ev_has
shops
prt_pvp
```
### Item Trade Restrictions
---
We want to ensure that specific items cannot be traded, sold, dropped, placed in storage, etc.
#### /db/import/item_trade.txt
#### /db/import/item_db.yml
// Legend for 'TradeMask' field (bitmask):
// 1 - item can't be dropped
// 2 - item can't be traded (nor vended)
// 4 - wedded partner can override restriction 2
// 8 - item can't be sold to npcs
// 16 - item can't be placed in the cart
// 32 - item can't be placed in the storage
// 64 - item can't be placed in the guild storage
// 128 - item can't be attached to mail
// 256 - item can't be auctioned
// Full outright value = 511
34000,511,100 // Old Green Box
34001,511,100 // House Keys
34002,511,100 // Reputation Journal
```yml
- Id: 34000 # Old Green Box
Trade:
NoDrop: true
NoTrade: true
TradePartner: true
NoSell: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
- Id: 34001 # House Keys
Trade:
NoDrop: true
NoTrade: true
TradePartner: true
NoSell: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
- Id: 34002 # Reputation Journal
Trade:
NoDrop: true
NoTrade: true
TradePartner: true
NoSell: true
NoCart: true
NoStorage: true
NoGuildStorage: true
NoMail: true
NoAuction: true
```
### Custom Quests
---
We want to add our own custom quests to the quest_db.
#### /db/import/quest_db.txt
#### /db/import/quest_db.yml
// Quest ID,Time Limit,Target1,Val1,Target2,Val2,Target3,Val3,MobID1,NameID1,Rate1,MobID2,NameID2,Rate2,MobID3,NameID3,Rate3,Quest Title
89001,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"Reputation Quest"
89002,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"Reputation Quest"
```yml
- Id: 89001
Title: "Reputation Quest"
- Id: 89002
Title: "Reputation Quest"
```

View File

@ -1229,6 +1229,12 @@ Don't expect things to run smoothly if you don't make your scripts 'end'.
---------------------------------------
*close3;
The command is similar to 'close' but the cutin (if any) is cleared after closing.
---------------------------------------
*end;
This command will stop the execution for this particular script. The two
@ -10276,7 +10282,7 @@ server and the egg will disappear when anyone tries to hatch it.
This function will return pet information for the pet the invoking character
currently has active. Valid types are:
PETINFO_ID - Pet ID
PETINFO_ID - Pet unique ID
PETINFO_CLASS - Pet class number as per 'db/(pre-)re/pet_db.yml' - will tell you what kind of a pet it is.
PETINFO_NAME - Pet name. Will return "null" if there's no pet.
PETINFO_INTIMATE - Pet friendly level (intimacy score). 1000 is full loyalty.
@ -10958,6 +10964,29 @@ If <char id> is specified, the specified player is used rather than the attached
---------------------------------------
*itemlink(<item_id>,<refine>,<card0>,<card1>,<card2>,<card3>,<enchantgrade>{,<RandomIDArray>,<RandomValueArray>,<RandomParamArray>});
Generates an item link string for an item that can be used for npctalk, message,
dispbottom, and broadcast commands. The result is a clickable-item name just
like SHIFT+Click from a player's inventory/cart/equipment window. This command can be
used with mes but the item name will not be clickable. You should use the normal client
tags for displaying item links in mes dialogues, if the client supports them.
Examples:
npctalk "Knife [3] : "+itemlink(1201)+"";
npctalk "+16 Knife [3] : "+itemlink(1201,16)+"";
npctalk "+13 BXB Bapho+VR+EA2+EA1 : "+itemlink(18110,13,4147,4407,4833,4832)+"";
setarray .@opt_ids[0],RDMOPT_VAR_ATKPERCENT,RDMOPT_VAR_ATKPERCENT,RDMOPT_VAR_ATTMPOWER,0,0;
setarray .@opt_values[0],3,5,20,0,0;
setarray .@opt_params[0],0,0,0,0,0;
npctalk "+13 BXB Bapho+VR+EA2+EA1 + 3 Options : "+itemlink(18110,13,4147,4407,4833,4832,0,.@opt_ids,.@opt_values,.@opt_params)+"";
RandomIDArray, RandomValueArray, and RandomParamArray only works if the
client (and server) supports the Item Random Options feature (PACKETVER >= 20150225).
========================
|14.- Channel commands.|
========================
@ -11227,3 +11256,9 @@ Returns fame rank (start from 1 to MAX_FAME_LIST), else 0.
Note: Only works with classes that use the ranking system.
---------------------------------------
*isdead({<account id>})
Returns true if the player is dead else false.
---------------------------------------

View File

@ -4,7 +4,7 @@ M_SRV=map-server
W_SRV=web-server
INST_PATH=/opt
PKG=rathena
PKG_PATH=$INST_PATH/$PKG
PKG_PATH="${INST_PATH}/${PKG}"
check_files() {
for i in ${L_SRV} ${C_SRV} ${M_SRV} ${W_SRV}
@ -17,11 +17,11 @@ check_files() {
}
check_inst_right(){
if [ ! -w $INST_PATH ]; then echo "You must have sudo right to use this install (write/read permission in /opt/ )" && exit; fi
if [ ! -w "${INST_PATH}" ]; then echo "You must have sudo right to use this install (write/read permission in ${INST_PATH}/ )" && exit; fi
}
inst_launch_workaround(){
if [ -d $PKG_PATH ]; then
if [ $(pwd) != $PKG_PATH ]; then cd $PKG_PATH; fi
if [ -d "${PKG_PATH}" ]; then
if [ "$(pwd)" != "${PKG_PATH}" ]; then cd "${PKG_PATH}"; fi
fi
}

View File

@ -6,12 +6,12 @@
# NOTE: This requires GNU getopt. On Mac OS X and FreeBSD, you have to install this
# separately; see below.
TEMP=`getopt -o d: -l destdir: -- "$@"`
TEMP=$(getopt -o d: -l destdir: -- "$@")
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
# Note the quotes around `$TEMP': they are essential!
eval set -- "$TEMP"
eval set -- "${TEMP}"
eval set -- "$TEMP"
eval set -- "${TEMP}"
while [ $# -gt 0 ]
do
case "$1" in
@ -20,26 +20,26 @@ do
shift
done
echo "destdir = $PKG_PATH "
echo "destdir = ${PKG_PATH} "
check_inst_right
check_files
mkdir -p $PKG_PATH/bin/
mkdir -p $PKG_PATH/etc/$PKG/
mkdir -p $PKG_PATH/usr/$PKG/
mkdir -p $PKG_PATH/var/$PKG/log
mkdir -p "${PKG_PATH}/bin/"
mkdir -p "${PKG_PATH}/etc/${PKG}/"
mkdir -p "${PKG_PATH}/usr/${PKG}/"
mkdir -p "${PKG_PATH}/var/${PKG}/log"
#we copy all file into opt/ dir and treat dir like normal unix arborescence
cp -r db/ $PKG_PATH/var/$PKG/db
if [ -d log ]; then cp -r log/* $PKG_PATH/var/$PKG/log/; fi
cp -r conf/ $PKG_PATH/etc/$PKG/conf
cp -r npc/ $PKG_PATH/usr/$PKG/npc
cp athena-start $PKG_PATH/
cp *-server* $PKG_PATH/bin/
cp -r db/ "${PKG_PATH}/var/${PKG}/db"
if [ -d log ]; then cp -r log/* "${PKG_PATH}/var/${PKG}/log/"; fi
cp -r conf/ "${PKG_PATH}/etc/${PKG}/conf"
cp -r npc/ "${PKG_PATH}/usr/${PKG}/npc"
cp athena-start "${PKG_PATH}/"
cp *-server* "${PKG_PATH}/bin/"
ln -fs $PKG_PATH/var/$PKG/db/ $PKG_PATH/db
ln -fs $PKG_PATH/var/$PKG/log/ $PKG_PATH/log
ln -fs $PKG_PATH/etc/$PKG/conf/ $PKG_PATH/conf
ln -fs $PKG_PATH/usr/$PKG/npc/ $PKG_PATH/npc
ln -fs $PKG_PATH/athena-start /usr/bin/$PKG
for f in $(ls $PKG_PATH/bin/) ; do ln -fs $PKG_PATH/bin/$f $PKG_PATH/$f; done
echo "Installation is done. You can now control the server with '$PKG start'"
ln -fs "${PKG_PATH}/var/${PKG}/db/" "${PKG_PATH}/db"
ln -fs "${PKG_PATH}/var/${PKG}/log/" "${PKG_PATH}/log"
ln -fs "${PKG_PATH}/etc/${PKG}/conf/" "${PKG_PATH}/conf"
ln -fs "${PKG_PATH}/usr/${PKG}/npc/" "${PKG_PATH}/npc"
ln -fs "${PKG_PATH}/athena-start" "/usr/bin/${PKG}"
for f in $(ls "${PKG_PATH}/bin/") ; do ln -fs "${PKG_PATH}/bin/${f}" "${PKG_PATH}/${f}"; done
echo "Installation is done. You can now control the server with '${PKG} start'"

View File

@ -53,7 +53,7 @@ L_SORRY:
M_FIN:
mes "[Exorcist Master Fahae]";
mes "The path of fully venquishing evil is far, help me in the way of God.";
mes "The path of fully vanquishing evil is far, help me in the way of God.";
close;
M_HERB:

View File

@ -0,0 +1,27 @@
//===== rAthena Script =======================================
//= Mapflag: No dynamic NPC map setting.
//===== Description: =========================================
//= Blocks the use of dynamic NPCs on a map.
//===== Additional Comments: =================================
//= 1.0 Initial script. [Lemongrass]
//============================================================
// Endless Tower
1@tower mapflag nodynamicnpc
2@tower mapflag nodynamicnpc
3@tower mapflag nodynamicnpc
4@tower mapflag nodynamicnpc
5@tower mapflag nodynamicnpc
6@tower mapflag nodynamicnpc
// Sealed Catacomb
1@cata mapflag nodynamicnpc
2@cata mapflag nodynamicnpc
// Orc's Memory
1@orcs mapflag nodynamicnpc
2@orcs mapflag nodynamicnpc
// Nidhoggur's Nest
1@nyd mapflag nodynamicnpc
2@nyd mapflag nodynamicnpc

View File

@ -752,15 +752,6 @@ function script F_GetPlatinumSkills {
return;
}
//////////////////////////////////////////////////////////////////////////////////
// Shortcut : close button and clear cutin.
//////////////////////////////////////////////////////////////////////////////////
function script close3 {
close2;
cutin "",255;
end;
}
//////////////////////////////////////////////////////////////////////////////////
// Return true if the card is a charm (enchant card), false otherwise.
//////////////////////////////////////////////////////////////////////////////////

View File

@ -7481,7 +7481,7 @@ OnTouch:
mes "Oh, please don't disturb";
mes "it's sleep. It hates that.";
mes "By the way, doesn't it";
mes "remind you of somehing?";
mes "remind you of something?";
mes "I mean, like maybe";
mes "a vagrant or a hobo?";
close;

View File

@ -366,7 +366,7 @@ dewata,95,203,6 script Travel Guide#dew 536,{
emotion ET_PROFUSELY_SWEAT;
next;
mes "[Guide]";
mes "Even in modern times Borobudur temple is a pilgimage site for many monks worshiping the Buddha. It's also a major tourist attraction, as you can imagine.";
mes "Even in modern times Borobudur temple is a pilgrimage site for many monks worshiping the Buddha. It's also a major tourist attraction, as you can imagine.";
emotion ET_PROFUSELY_SWEAT;
next;
mes "[Guide]";

View File

@ -266,7 +266,7 @@ OnMyMobDead:
mes "[Avant]";
mes "Did something happen to you?";
mes "There was a subtle and magical echo to it.";
mes "Immidiately after that, you were thrown here.";
mes "Immediately after that, you were thrown here.";
next;
if (select("It's all because of you!:Shenime said...") == 1) {
mes "[Avant]";

View File

@ -533,7 +533,7 @@ OnMobDead:
killmonster 'map_begi$, instance_npcname("poring_village_2") + "::OnMobDead";
mapannounce 'map_begi$, "Emily: Hmm.. here is another Boss... It looks strong...", bc_map, 0xFFFF00;
sleep 2000;
mapannounce 'map_begi$, "Emily: I'm not good at battle.. Let me look for tresure first. See you soon~", bc_map, 0xFFFF00;
mapannounce 'map_begi$, "Emily: I'm not good at battle.. Let me look for treasure first. See you soon~", bc_map, 0xFFFF00;
sleep 2000;
monster 'map_begi$,42,173,"--en--","MD_AMERING",1, instance_npcname("poring_village_2") + "::OnBossDead";
end;

View File

@ -0,0 +1,140 @@
//===== rAthena Script =======================================
//= Mapflag: No dynamic NPC map setting.
//===== Description: =========================================
//= Blocks the use of dynamic NPCs on a map.
//===== Additional Comments: =================================
//= 1.0 Initial script. [Lemongrass]
//============================================================
// Mistwood Maze
1@mist mapflag nodynamicnpc
// Culvert
1@pump mapflag nodynamicnpc
2@pump mapflag nodynamicnpc
// Octopus Cave
1@cash mapflag nodynamicnpc
// Bangungot Hospital 2F
1@ma_h mapflag nodynamicnpc
// Buwaya Cave
1@ma_c mapflag nodynamicnpc
// Bakonawa Lake
1@ma_b mapflag nodynamicnpc
// Wolfchev's Laboratory
1@lhz mapflag nodynamicnpc
// Old Glast Heim
1@gl_k mapflag nodynamicnpc
2@gl_k mapflag nodynamicnpc
// Eclage Interior
1@ecl mapflag nodynamicnpc
// Sara's Memories
1@sara mapflag nodynamicnpc
// Geffen Magic Tournament
1@gef mapflag nodynamicnpc
1@gef_in mapflag nodynamicnpc
1@ge_st mapflag nodynamicnpc
// Horror Toy Factory
1@xm_d mapflag nodynamicnpc
// Faceworm's Nest
1@face mapflag nodynamicnpc
// Ghost Palace
1@spa mapflag nodynamicnpc
// Devil's Tower
1@tnm1 mapflag nodynamicnpc
1@tnm2 mapflag nodynamicnpc
1@tnm3 mapflag nodynamicnpc
// Assault on the Airship
1@air1 mapflag nodynamicnpc
1@air2 mapflag nodynamicnpc
// Fenrir and Sarah
1@glast mapflag nodynamicnpc
// Wave Mode - Forest
1@def01 mapflag nodynamicnpc
// Wave Mode - Sky
1@def02 mapflag nodynamicnpc
// Nightmarish Jitterbug
1@jtb mapflag nodynamicnpc
// Isle of Bios
1@dth1 mapflag nodynamicnpc
1@dth2 mapflag nodynamicnpc
1@dth3 mapflag nodynamicnpc
// Morse's Cave
1@rev mapflag nodynamicnpc
// Temple of the Demon God
1@eom mapflag nodynamicnpc
// Central Laboratory
1@lab mapflag nodynamicnpc
// Last room
1@uns mapflag nodynamicnpc
// Charleston in Distress
1@mcd mapflag nodynamicnpc
// Ritual of Blessing
2@mir mapflag nodynamicnpc
// Room of Consciousness
1@mir mapflag nodynamicnpc
// Sky Fortress Invasion
1@sthb mapflag nodynamicnpc
1@sthc mapflag nodynamicnpc
1@sthd mapflag nodynamicnpc
// Heart Hunter War Base 1 + 2
1@swat mapflag nodynamicnpc
// Werner Laboratory central room#1 + 2
1@slw mapflag nodynamicnpc
// Infinite Space
1@infi mapflag nodynamicnpc
// Regenschirm
1@rgsr mapflag nodynamicnpc
// Sealed OS
1@os_b mapflag nodynamicnpc
// OS Occupation + 2nd OS Search
1@os_a mapflag nodynamicnpc
// Cor Memorial
1@cor mapflag nodynamicnpc
// Half Moon In The Daylight
1@pop1 mapflag nodynamicnpc
1@pop2 mapflag nodynamicnpc
1@pop3 mapflag nodynamicnpc
// Weekend Dungeon
1@md_pay mapflag nodynamicnpc
// Friday Dungeon
1@md_gef mapflag nodynamicnpc
// Poring Village
1@begi mapflag nodynamicnpc

File diff suppressed because it is too large Load Diff

View File

@ -205,6 +205,7 @@ npc: npc/re/quests/seals/megingard_seal.txt
// --------------------------------------------------------------
npc: npc/re/quests/cooking_quest.txt
//npc: npc/re/quests/cupet.txt
npc: npc/re/quests/HelpMeShorty.txt
npc: npc/re/quests/homun_s.txt
npc: npc/re/quests/juno_monster_society.txt
npc: npc/re/quests/magic_books.txt

View File

@ -0,0 +1,15 @@
function script AssertTrue {
if (!getarg(0)) {
errormes "AssertTrue failed for " + getarg(1) + ".";
return false;
}
return true;
}
function script AssertEquals {
if (getarg(0) != getarg(1)) {
errormes "AssertEquals failed for " + getarg(2) + ": expected " + getarg(0) + ", got " + getarg(1) + ".";
return false;
}
return true;
}

35
npc/test/ci/7291.txt Normal file
View File

@ -0,0 +1,35 @@
- script itemlink#ci -1,{
OnInit:
if( checkre(0) ){
if( PACKETVER >= 20200916 ){
.@expected$ = "<ITEML>0000213v0%0g&00'00)18X)1ck)00)00+2R,00-00</ITEML>";
}else if( PACKETVER >= 20150225 ){
// Grade does not exist (clientside) yet
.@expected$ = "<ITEMLINK>0000213v0%0g&00(18X(1ck(00(00*2R+00,00</ITEMLINK>";
}else if( PACKETVER >= 20100000 ){
// Random Options do not exist (clientside) yet
.@expected$ = "<ITEMLINK>0000213v0%0g&00(18X(1ck(00(00</ITEMLINK>";
}else{
// Item Link does not exist (clientside) yet
.@expected$ = "Crimson Saber";
}
setarray .@opt_ids,RDMOPT_WEAPON_ATTR_GROUND;
.@actual$ = itemlink(13454,16,4399,4608,0,0,0,.@opt_ids,.@opt_dummy,.@opt_dummy);
AssertEquals(.@expected$, .@actual$, "Generated itemlink for +16 Earth Crimson Saber");
}else{
if( PACKETVER >= 20200916 ){
.@expected$ = "<ITEML>000021hS%0a&00'00)18X)00)00)00</ITEML>";
}else if( PACKETVER >= 20100000 ){
// Grade does not exist (clientside) yet// Grade does not exist (clientside) yet
.@expected$ = "<ITEMLINK>000021hS%0a&00(18X(00(00(00</ITEMLINK>";
}else{
// Item Link does not exist (clientside) yet
.@expected$ = "Blade";
}
// No Random Options in Pre-Renewal
.@actual$ = itemlink(1108,10,4399);
AssertEquals(.@expected$, .@actual$, "Generated itemlink for +10 Blade[4]");
}
}

View File

@ -3010,7 +3010,11 @@ bool char_config_read(const char* cfgName, bool normal){
charserv_config.start_zeny = atoi(w2);
if (charserv_config.start_zeny < 0)
charserv_config.start_zeny = 0;
#ifdef RENEWAL
} else if (strcmpi(w1, "start_items") == 0) {
#else
} else if (strcmpi(w1, "start_items_pre") == 0) {
#endif
char_config_split_startitem(w1, w2, charserv_config.start_items);
#if PACKETVER >= 20151001
} else if (strcmpi(w1, "start_items_doram") == 0) {

View File

@ -114,3 +114,33 @@ bool rathena::util::safe_multiplication( int64 a, int64 b, int64& result ){
return false;
#endif
}
void rathena::util::string_left_pad_inplace(std::string& str, char padding, size_t num)
{
str.insert(0, min(0, num - str.length()), padding);
}
std::string rathena::util::string_left_pad(const std::string& original, char padding, size_t num)
{
return std::string(num - min(num, original.length()), padding) + original;
}
constexpr char base62_dictionary[] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D',
'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z'
};
std::string rathena::util::base62_encode( uint32 val ){
std::string result = "";
while (val != 0) {
result = base62_dictionary[(val % 62)] + result;
val /= 62;
}
return result;
}

View File

@ -285,6 +285,31 @@ namespace rathena {
template <typename T> void tolower( T& string ){
std::transform( string.begin(), string.end(), string.begin(), ::tolower );
}
/**
* Pad string with arbitrary character in-place
* @param str: String to pad
* @param padding: Padding character
* @param num: Maximum length of padding
*/
void string_left_pad_inplace(std::string& str, char padding, size_t num);
/**
* Pad string with arbitrary character
* @param original: String to pad
* @param padding: Padding character
* @param num: Maximum length of padding
*
* @return A copy of original string with padding added
*/
std::string string_left_pad(const std::string& original, char padding, size_t num);
/**
* Encode base10 number to base62. Originally by lututui
* @param val: Base10 Number
* @return Base62 string
**/
std::string base62_encode( uint32 val );
}
}

View File

@ -4007,7 +4007,7 @@ ACMD_FUNC(idsearch)
for(const auto &result : item_array) {
std::shared_ptr<item_data> id = result.second;
sprintf(atcmd_output, msg_txt(sd,78), id->ename.c_str(), id->nameid); // %s: %u
sprintf(atcmd_output, msg_txt(sd,78), item_db.create_item_link( id->nameid ).c_str(), id->nameid); // %s: %u
clif_displaymessage(fd, atcmd_output);
}
sprintf(atcmd_output, msg_txt(sd,79), match); // It is %d affair above.
@ -6678,7 +6678,7 @@ ACMD_FUNC(autolootitem)
return -1;
}
sd->state.autolootid[i] = item_data->nameid; // Autoloot Activated
sprintf(atcmd_output, msg_txt(sd,1192), item_data->name.c_str(), item_data->ename.c_str(), item_data->nameid); // Autolooting item: '%s'/'%s' {%u}
sprintf(atcmd_output, msg_txt(sd,1192), item_data->name.c_str(), item_db.create_item_link( item_data->nameid ).c_str(), item_data->nameid); // Autolooting item: '%s'/'%s' {%u}
clif_displaymessage(fd, atcmd_output);
sd->state.autolooting = 1;
break;
@ -6689,7 +6689,7 @@ ACMD_FUNC(autolootitem)
return -1;
}
sd->state.autolootid[i] = 0;
sprintf(atcmd_output, msg_txt(sd,1194), item_data->name.c_str(), item_data->ename.c_str(), item_data->nameid); // Removed item: '%s'/'%s' {%u} from your autolootitem list.
sprintf(atcmd_output, msg_txt(sd,1194), item_data->name.c_str(), item_db.create_item_link( item_data->nameid ).c_str(), item_data->nameid); // Removed item: '%s'/'%s' {%u} from your autolootitem list.
clif_displaymessage(fd, atcmd_output);
ARR_FIND(0, AUTOLOOTITEM_SIZE, i, sd->state.autolootid[i] != 0);
if (i == AUTOLOOTITEM_SIZE) {
@ -6717,7 +6717,7 @@ ACMD_FUNC(autolootitem)
continue;
}
sprintf(atcmd_output, "'%s'/'%s' {%u}", item_data->name.c_str(), item_data->ename.c_str(), item_data->nameid);
sprintf(atcmd_output, "'%s'/'%s' {%u}", item_data->name.c_str(), item_db.create_item_link( item_data->nameid ).c_str(), item_data->nameid);
clif_displaymessage(fd, atcmd_output);
}
}
@ -7784,9 +7784,9 @@ ACMD_FUNC(mobinfo)
int droprate = mob_getdroprate( &sd->bl, mob, mob->dropitem[i].rate, drop_modifier );
if (id->slots)
sprintf(atcmd_output2, " - %s[%d] %02.02f%%", id->ename.c_str(), id->slots, (float)droprate / 100);
sprintf(atcmd_output2, " - %s[%d] %02.02f%%", item_db.create_item_link( id->nameid ).c_str(), id->slots, (float)droprate / 100);
else
sprintf(atcmd_output2, " - %s %02.02f%%", id->ename.c_str(), (float)droprate / 100);
sprintf(atcmd_output2, " - %s %02.02f%%", item_db.create_item_link( id->nameid ).c_str(), (float)droprate / 100);
strcat(atcmd_output, atcmd_output2);
if (++j % 3 == 0) {
clif_displaymessage(fd, atcmd_output);
@ -7824,14 +7824,14 @@ ACMD_FUNC(mobinfo)
j++;
if (j == 1) {
if (id->slots)
sprintf(atcmd_output2, " %s[%d] %02.02f%%", id->ename.c_str(), id->slots, mvppercent);
sprintf(atcmd_output2, " %s[%d] %02.02f%%", item_db.create_item_link( id->nameid ).c_str(), id->slots, mvppercent);
else
sprintf(atcmd_output2, " %s %02.02f%%", id->ename.c_str(), mvppercent);
sprintf(atcmd_output2, " %s %02.02f%%", item_db.create_item_link( id->nameid ).c_str(), mvppercent);
} else {
if (id->slots)
sprintf(atcmd_output2, " - %s[%d] %02.02f%%", id->ename.c_str(), id->slots, mvppercent);
sprintf(atcmd_output2, " - %s[%d] %02.02f%%", item_db.create_item_link( id->nameid ).c_str(), id->slots, mvppercent);
else
sprintf(atcmd_output2, " - %s %02.02f%%", id->ename.c_str(), mvppercent);
sprintf(atcmd_output2, " - %s %02.02f%%", item_db.create_item_link( id->nameid ).c_str(), mvppercent);
}
strcat(atcmd_output, atcmd_output2);
}
@ -8266,7 +8266,7 @@ ACMD_FUNC(iteminfo)
std::shared_ptr<item_data> item_data = result.second;
sprintf(atcmd_output, msg_txt(sd,1277), // Item: '%s'/'%s'[%d] (%u) Type: %s | Extra Effect: %s
item_data->name.c_str(),item_data->ename.c_str(),item_data->slots,item_data->nameid,
item_data->name.c_str(), item_db.create_item_link( item_data->nameid ).c_str(),item_data->slots,item_data->nameid,
(item_data->type != IT_AMMO) ? itemdb_typename((enum item_types)item_data->type) : itemdb_typename_ammo((e_ammo_type)item_data->subtype),
(item_data->script==NULL)? msg_txt(sd,1278) : msg_txt(sd,1279) // None / With script
);
@ -8323,7 +8323,7 @@ ACMD_FUNC(whodrops)
for (const auto &result : item_array) {
std::shared_ptr<item_data> id = result.second;
sprintf(atcmd_output, msg_txt(sd,1285), id->ename.c_str(), id->slots, id->nameid); // Item: '%s'[%d] (ID:%u)
sprintf(atcmd_output, msg_txt(sd,1285), item_db.create_item_link( id->nameid ).c_str(), id->slots, id->nameid); // Item: '%s'[%d] (ID:%u)
clif_displaymessage(fd, atcmd_output);
if (id->mob[0].chance == 0) {
@ -9319,9 +9319,9 @@ ACMD_FUNC(itemlist)
}
if( it->refine )
StringBuf_Printf(&buf, "%d %s %+d (%s, id: %u)", it->amount, itd->ename.c_str(), it->refine, itd->name.c_str(), it->nameid);
StringBuf_Printf(&buf, "%d %s %+d (%s, id: %u)", it->amount, item_db.create_item_link( it->nameid ).c_str(), it->refine, itd->name.c_str(), it->nameid);
else
StringBuf_Printf(&buf, "%d %s (%s, id: %u)", it->amount, itd->ename.c_str(), itd->name.c_str(), it->nameid);
StringBuf_Printf(&buf, "%d %s (%s, id: %u)", it->amount, item_db.create_item_link( it->nameid ).c_str(), itd->name.c_str(), it->nameid);
if( it->equip ) {
char equipstr[CHAT_SIZE_MAX];
@ -9424,7 +9424,7 @@ ACMD_FUNC(itemlist)
if( counter2 != 1 )
StringBuf_AppendStr(&buf, ", ");
StringBuf_Printf(&buf, "#%d %s (id: %u)", counter2, card->ename.c_str(), card->nameid);
StringBuf_Printf(&buf, "#%d %s (id: %u)", counter2, item_db.create_item_link( card->nameid ).c_str(), card->nameid);
}
if( counter2 > 0 )
@ -10821,6 +10821,24 @@ ACMD_FUNC( enchantgradeui ){
#endif
}
ACMD_FUNC( roulette ){
nullpo_retr( -1, sd );
#if PACKETVER < 20141022
sprintf( atcmd_output, msg_txt( sd, 798 ), "2014-10-22" ); // This command requires packet version %s or newer.
clif_displaymessage( fd, atcmd_output );
return -1;
#else
if( !battle_config.feature_roulette ){
clif_displaymessage( fd, msg_txt( sd, 1497 ) ); // Roulette is disabled
return -1;
}
clif_roulette_open( sd );
return 0;
#endif
}
#include "../custom/atcommand.inc"
/**
@ -11145,6 +11163,7 @@ void atcommand_basecommands(void) {
ACMD_DEFR(stylist, ATCMD_NOCONSOLE|ATCMD_NOAUTOTRADE),
ACMD_DEF(addfame),
ACMD_DEFR(enchantgradeui, ATCMD_NOCONSOLE|ATCMD_NOAUTOTRADE),
ACMD_DEFR(roulette, ATCMD_NOCONSOLE|ATCMD_NOAUTOTRADE),
};
AtCommandInfo* atcommand;
int i;

View File

@ -10267,6 +10267,7 @@ static const struct _battle_data {
{ "feature.barter", &battle_config.feature_barter, 1, 0, 1, },
{ "feature.barter_extended", &battle_config.feature_barter_extended, 1, 0, 1, },
{ "feature.itemlink", &battle_config.feature_itemlink, 1, 0, 1, },
{ "break_mob_equip", &battle_config.break_mob_equip, 0, 0, 1, },
{ "macro_detection_retry", &battle_config.macro_detection_retry, 3, 1, INT_MAX, },
{ "macro_detection_timeout", &battle_config.macro_detection_timeout, 60000, 0, INT_MAX, },

View File

@ -563,6 +563,7 @@ struct Battle_Config
int discount_item_point_shop;
int update_enemy_position;
int devotion_rdamage;
int feature_itemlink;
// autotrade persistency
int feature_autotrade;

View File

@ -1637,8 +1637,7 @@ void chrif_parse_ack_vipActive(int fd) {
// Show info if status changed
if (((flag&0x4) || changed) && !sd->vip.disableshowrate) {
clif_display_pinfo(sd,ZC_PERSONAL_INFOMATION);
//clif_vip_display_info(sd,ZC_PERSONAL_INFOMATION_CHN);
clif_display_pinfo( *sd );
}
#endif
}

View File

@ -79,7 +79,6 @@ static inline int32 client_exp(t_exp exp) {
static struct eri *delay_clearunit_ers;
struct s_packet_db packet_db[MAX_PACKET_DB + 1];
int packet_db_ack[MAX_ACK_FUNC + 1];
// Reuseable global packet buffer to prevent too many allocations
// Take socket.cpp::socket_max_client_packet into consideration
static int8 packet_buffer[UINT16_MAX];
@ -2491,25 +2490,13 @@ void clif_scriptclose(struct map_session_data *sd, int npcid)
* @param sd : player pointer
* @param npcid : npc gid to close
*/
void clif_scriptclear(struct map_session_data *sd, int npcid)
{
struct s_packet_db* info;
int16 len;
int cmd = 0;
int fd;
void clif_scriptclear( struct map_session_data& sd, int npcid ){
struct PACKET_ZC_CLEAR_DIALOG p = {};
nullpo_retv(sd);
p.packetType = HEADER_ZC_CLEAR_DIALOG;
p.GID = npcid;
cmd = packet_db_ack[ZC_CLEAR_DIALOG];
if(!cmd) cmd = 0x8d6; //default
info = &packet_db[cmd];
len = info->len;
fd = sd->fd;
WFIFOHEAD(fd, len);
WFIFOW(fd,0)=0x8d6;
WFIFOL(fd,info->pos[0])=npcid;
WFIFOSET(fd,len);
clif_send( &p, sizeof( p ), &sd.bl, SELF );
}
/*==========================================
@ -4134,48 +4121,22 @@ void clif_statusupack(struct map_session_data *sd,int type,int ok,int val) {
/// 0 = failure
/// 1 = success
/// 2 = failure due to low level
void clif_equipitemack(struct map_session_data *sd,int n,int pos,uint8 flag)
{
int fd = 0, cmd = 0, look = 0;
struct s_packet_db *info = NULL;
void clif_equipitemack( struct map_session_data& sd, uint8 flag, int index, int pos ){
struct PACKET_ZC_REQ_WEAR_EQUIP_ACK p = {};
nullpo_retv(sd);
cmd = packet_db_ack[ZC_WEAR_EQUIP_ACK];
if (!cmd || !(info = &packet_db[cmd]) || !info->len)
return;
fd = sd->fd;
if (flag == ITEM_EQUIP_ACK_OK && sd->inventory_data[n]->equip&EQP_VISIBLE)
look = sd->inventory_data[n]->look;
WFIFOHEAD(fd, info->len);
WFIFOW(fd, 0) = cmd;
WFIFOW(fd, info->pos[0]) = n+2;
switch (cmd) {
case 0xaa:
WFIFOW(fd, info->pos[1]) = pos;
#if PACKETVER < 20100629
WFIFOW(fd, info->pos[2]) = (flag == ITEM_EQUIP_ACK_OK ? 1 : 0);
#else
WFIFOL(fd, info->pos[2]) = look;
WFIFOW(fd, info->pos[3]) = (flag == ITEM_EQUIP_ACK_OK ? 1 : 0);
#endif
break;
case 0x8d0:
if (flag == ITEM_EQUIP_ACK_FAILLEVEL)
flag = 1;
case 0x999:
if (cmd == 0x999)
WFIFOL(fd, info->pos[1]) = pos;
else
WFIFOW(fd, info->pos[1]) = pos;
WFIFOL(fd, info->pos[2]) = look;
WFIFOW(fd, info->pos[3]) = flag;
break;
p.PacketType = HEADER_ZC_REQ_WEAR_EQUIP_ACK;
p.index = client_index( index );
p.wearLocation = pos;
#if PACKETVER_MAIN_NUM >= 20101123 || PACKETVER_RE_NUM >= 20100629
if( flag == ITEM_EQUIP_ACK_OK && sd.inventory_data[index]->equip&EQP_VISIBLE ){
p.wItemSpriteNumber = sd.inventory_data[index]->look;
}else{
p.wItemSpriteNumber = 0;
}
WFIFOSET(fd, info->len);
#endif
p.result = flag;
clif_send( &p, sizeof( p ), &sd.bl, SELF );
}
@ -7346,16 +7307,15 @@ void clif_cart_additem_ack(struct map_session_data *sd, uint8 flag)
}
// 09B7 <unknow data> (ZC_ACK_OPEN_BANKING)
void clif_bank_open(struct map_session_data *sd){
int fd;
void clif_bank_open( struct map_session_data& sd ){
#if PACKETVER >= 20130717
struct PACKET_ZC_ACK_OPEN_BANKING p = {};
nullpo_retv(sd);
fd = sd->fd;
p.packetType = HEADER_ZC_ACK_OPEN_BANKING;
p.unknown = 0;
WFIFOHEAD(fd,4);
WFIFOW(fd,0) = 0x09b7;
WFIFOW(fd,2) = 0;
WFIFOSET(fd,4);
clif_send( &p, sizeof( p ), &sd.bl, SELF );
#endif
}
/*
@ -7378,23 +7338,21 @@ void clif_parse_BankOpen(int fd, struct map_session_data* sd) {
//request save ?
//chrif_bankdata_request(sd->status.account_id, sd->status.char_id);
//on succes open bank ?
clif_bank_open(sd);
clif_bank_open( *sd );
}
}
}
// 09B9 <unknow data> (ZC_ACK_CLOSE_BANKING)
void clif_bank_close( struct map_session_data& sd ){
#if PACKETVER >= 20130717
struct PACKET_ZC_ACK_CLOSE_BANKING p = {};
void clif_bank_close(struct map_session_data *sd){
int fd;
p.packetType = HEADER_ZC_ACK_CLOSE_BANKING;
p.unknown = 0;
nullpo_retv(sd);
fd = sd->fd;
WFIFOHEAD(fd,4);
WFIFOW(fd,0) = 0x09B9;
WFIFOW(fd,2) = 0;
WFIFOSET(fd,4);
clif_send( &p, sizeof( p ), &sd.bl, SELF );
#endif
}
/*
@ -7412,33 +7370,24 @@ void clif_parse_BankClose(int fd, struct map_session_data* sd) {
}
if(sd->status.account_id == aid){
sd->state.banking = 0;
clif_bank_close(sd);
clif_bank_close( *sd );
}
}
/*
* Display how much we got in bank (I suppose)
09A6 <Bank_Vault>Q <Reason>W (PACKET_ZC_BANKING_CHECK)
* 09A6 <Bank_Vault>Q <Reason>W (ZC_BANKING_CHECK)
*/
void clif_Bank_Check(struct map_session_data* sd) {
unsigned char buf[13];
struct s_packet_db* info;
int16 len;
int cmd = 0;
void clif_Bank_Check( struct map_session_data& sd ){
#if PACKETVER >= 20130717
struct PACKET_ZC_BANKING_CHECK p = {};
nullpo_retv(sd);
p.packetType = HEADER_ZC_BANKING_CHECK;
p.money = sd.bank_vault;
p.reason = 0;
cmd = packet_db_ack[ZC_BANKING_CHECK];
if(!cmd) cmd = 0x09A6; //default
info = &packet_db[cmd];
len = info->len;
if(!len) return; //version as packet disable
// sd->state.banking = 1; //mark opening and closing
WBUFW(buf,0) = cmd;
WBUFQ(buf,info->pos[0]) = sd->bank_vault; //value
WBUFW(buf,info->pos[1]) = 0; //reason
clif_send(buf,len,&sd->bl,SELF);
clif_send( &p, sizeof( p ), &sd.bl, SELF );
#endif
}
/*
@ -7456,7 +7405,7 @@ void clif_parse_BankCheck(int fd, struct map_session_data* sd) {
struct s_packet_db* info = &packet_db[RFIFOW(fd,0)];
int aid = RFIFOL(fd,info->pos[0]); //unused should we check vs fd ?
if(sd->status.account_id == aid) //since we have it let check it for extra security
clif_Bank_Check(sd);
clif_Bank_Check( *sd );
}
}
@ -7464,25 +7413,17 @@ void clif_parse_BankCheck(int fd, struct map_session_data* sd) {
* Acknowledge of deposit some money in bank
09A8 <Reason>W <Money>Q <balance>L (PACKET_ZC_ACK_BANKING_DEPOSIT)
*/
void clif_bank_deposit(struct map_session_data *sd, enum e_BANKING_DEPOSIT_ACK reason) {
unsigned char buf[17];
struct s_packet_db* info;
int16 len;
int cmd =0;
void clif_bank_deposit( struct map_session_data& sd, enum e_BANKING_DEPOSIT_ACK reason ){
#if PACKETVER >= 20130717
struct PACKET_ZC_ACK_BANKING_DEPOSIT p = {};
nullpo_retv(sd);
p.packetType = HEADER_ZC_ACK_BANKING_DEPOSIT;
p.money = sd.bank_vault;
p.zeny = sd.status.zeny;
p.reason = reason;
cmd = packet_db_ack[ZC_ACK_BANKING_DEPOSIT];
if(!cmd) cmd = 0x09A8;
info = &packet_db[cmd];
len = info->len;
if(!len) return; //version as packet disable
WBUFW(buf,0) = cmd;
WBUFW(buf,info->pos[0]) = (short)reason;
WBUFQ(buf,info->pos[1]) = sd->bank_vault;/* money in the bank */
WBUFL(buf,info->pos[2]) = sd->status.zeny;/* how much zeny char has after operation */
clif_send(buf,len,&sd->bl,SELF);
clif_send( &p, sizeof( p ), &sd.bl, SELF );
#endif
}
/*
@ -7503,7 +7444,7 @@ void clif_parse_BankDeposit(int fd, struct map_session_data* sd) {
if(sd->status.account_id == aid){
enum e_BANKING_DEPOSIT_ACK reason = pc_bank_deposit(sd,max(0,money));
clif_bank_deposit(sd,reason);
clif_bank_deposit( *sd, reason );
}
}
}
@ -7512,26 +7453,17 @@ void clif_parse_BankDeposit(int fd, struct map_session_data* sd) {
* Acknowledge of withdrawing some money from bank
09AA <Reason>W <Money>Q <balance>L (PACKET_ZC_ACK_BANKING_WITHDRAW)
*/
void clif_bank_withdraw(struct map_session_data *sd,enum e_BANKING_WITHDRAW_ACK reason) {
unsigned char buf[17];
struct s_packet_db* info;
int16 len;
int cmd;
void clif_bank_withdraw( struct map_session_data& sd, enum e_BANKING_WITHDRAW_ACK reason ){
#if PACKETVER >= 20130717
struct PACKET_ZC_ACK_BANKING_WITHDRAW p = {};
nullpo_retv(sd);
p.packetType = HEADER_ZC_ACK_BANKING_WITHDRAW;
p.reason = reason;
p.money = sd.bank_vault;
p.zeny = sd.status.zeny;
cmd = packet_db_ack[ZC_ACK_BANKING_WITHDRAW];
if(!cmd) cmd = 0x09AA;
info = &packet_db[cmd];
len = info->len;
if(!len) return; //version as packet disable
WBUFW(buf,0) = cmd;
WBUFW(buf,info->pos[0]) = (short)reason;
WBUFQ(buf,info->pos[1]) = sd->bank_vault;/* money in the bank */
WBUFL(buf,info->pos[2]) = sd->status.zeny;/* how much zeny char has after operation */
clif_send(buf,len,&sd->bl,SELF);
clif_send( &p, sizeof( p ), &sd.bl, SELF );
#endif
}
/*
@ -7550,7 +7482,7 @@ void clif_parse_BankWithdraw(int fd, struct map_session_data* sd) {
int money = RFIFOL(fd,info->pos[1]);
if(sd->status.account_id == aid){
enum e_BANKING_WITHDRAW_ACK reason = pc_bank_withdraw(sd,max(0,money));
clif_bank_withdraw(sd,reason);
clif_bank_withdraw( *sd, reason );
}
}
}
@ -11088,8 +11020,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
map_getmapflag(sd->state.pmap, MF_BEXP) != mapdata->flag[MF_BEXP]
)
{
clif_display_pinfo(sd,ZC_PERSONAL_INFOMATION);
//clif_vip_display_info(sd,ZC_PERSONAL_INFOMATION_CHN);
clif_display_pinfo( *sd );
}
#endif
@ -12094,7 +12025,7 @@ void clif_parse_EquipItem(int fd,struct map_session_data *sd)
return;
if(!sd->inventory.u.items_inventory[index].identify) {
clif_equipitemack(sd,index,0,ITEM_EQUIP_ACK_FAIL); // fail
clif_equipitemack( *sd, ITEM_EQUIP_ACK_FAIL, index ); // fail
return;
}
@ -19957,19 +19888,16 @@ void clif_update_rankingpoint(map_session_data &sd, int rankingtype, int point)
* 0 - map adjustment (bexp mapflag), 1 - Premium/VIP adjustment, 2 - Server rate adjustment, 3 - None
*/
#ifdef VIP_ENABLE
void clif_display_pinfo(struct map_session_data *sd, int cmdtype) {
if (sd) {
struct s_packet_db* info;
int16 len, szdetails = 13, maxinfotype = PINFO_MAX;
int cmd = 0, fd, i = 0;
int tot_baseexp = 100, tot_penalty = 100, tot_drop = 100, factor = 1000;
void clif_display_pinfo( struct map_session_data& sd ){
#if PACKETVER_MAIN_NUM >= 20110627 || PACKETVER_RE_NUM >= 20110628 || defined(PACKETVER_ZERO)
// TODO: Whoever wants to take the blame, fix this crappy logic below - and yes I know indentation is wrong, but CANT TOUCH THIS! *sings* [Lemongrass]
int details_bexp[PINFO_MAX], details_drop[PINFO_MAX], details_penalty[PINFO_MAX];
/**
* EXP
*/
//0:PCRoom
details_bexp[PINFO_BASIC] = map_getmapflag(sd->bl.m, MF_BEXP);
details_bexp[PINFO_BASIC] = map_getmapflag( sd.bl.m, MF_BEXP );
if (details_bexp[PINFO_BASIC] == 100 || !details_bexp[PINFO_BASIC])
details_bexp[PINFO_BASIC] = 0;
else {
@ -19981,7 +19909,7 @@ void clif_display_pinfo(struct map_session_data *sd, int cmdtype) {
}
//1:Premium
if (pc_isvip(sd)) {
if( pc_isvip( &sd ) ){
details_bexp[PINFO_PREMIUM] = battle_config.vip_base_exp_increase * battle_config.base_exp_rate / 100;
if (details_bexp[PINFO_PREMIUM] < 0)
details_bexp[PINFO_PREMIUM] = 0 - details_bexp[PINFO_PREMIUM];
@ -20010,7 +19938,7 @@ void clif_display_pinfo(struct map_session_data *sd, int cmdtype) {
details_drop[PINFO_BASIC] = 0;
//1:Premium
if (pc_isvip(sd)) {
if( pc_isvip( &sd ) ){
details_drop[PINFO_PREMIUM] = (battle_config.vip_drop_increase * battle_config.item_rate_common) / 100;
if (details_drop[PINFO_PREMIUM] < 0)
details_drop[PINFO_PREMIUM] = 0 - details_drop[PINFO_PREMIUM];
@ -20040,7 +19968,7 @@ void clif_display_pinfo(struct map_session_data *sd, int cmdtype) {
details_penalty[PINFO_BASIC] = 0;
//1:Premium
if (pc_isvip(sd)) {
if( pc_isvip( &sd ) ){
details_penalty[PINFO_PREMIUM] = battle_config.vip_exp_penalty_base;
if (details_penalty[PINFO_PREMIUM] == 100)
details_penalty[PINFO_PREMIUM] = 0;
@ -20071,53 +19999,40 @@ void clif_display_pinfo(struct map_session_data *sd, int cmdtype) {
//3:TPLUS
details_penalty[PINFO_CAFE] = 0;
cmd = packet_db_ack[cmdtype];
info = &packet_db[cmd];
len = info->len; //this is the base len without details
if(!len) return; //version as packet disable
struct PACKET_ZC_PERSONAL_INFOMATION* p = (struct PACKET_ZC_PERSONAL_INFOMATION*)packet_buffer;
if (cmdtype == ZC_PERSONAL_INFOMATION && cmd == 0x08cb) { //0x08cb version
szdetails = 7;
factor = 1;
}
else if (cmd == 0x097b) {
tot_baseexp *= factor;
tot_drop *= factor;
tot_penalty *= factor;
p->packetType = HEADER_ZC_PERSONAL_INFOMATION;
p->length = sizeof( *p ) + PINFO_MAX * sizeof( p->details[0] );
#if PACKETVER_MAIN_NUM >= 20120503 || PACKETVER_RE_NUM >= 20120502 || defined(PACKETVER_ZERO)
p->total_exp = 100 * 1000;
p->total_death = 100 * 1000;
p->total_drop = 100 * 1000;
#else
p->total_exp = 100;
p->total_death = 100;
p->total_drop = 100;
#endif
for( int i = PINFO_BASIC; i < PINFO_MAX; i++ ){
p->details[i].type = i; // infotype 0 PCRoom, 1 Premium, 2 Server, 3 TPlus
#if PACKETVER_MAIN_NUM >= 20120503 || PACKETVER_RE_NUM >= 20120502 || defined(PACKETVER_ZERO)
p->details[i].exp = details_bexp[i] * 1000;
p->details[i].death = details_penalty[i] * 1000;
p->details[i].drop = details_drop[i] * 1000;
#else
p->details[i].exp = details_bexp[i];
p->details[i].death = details_penalty[i];
p->details[i].drop = details_drop[i];
#endif
p->total_exp += p->details[i].exp;
p->total_death += p->details[i].death;
p->total_drop += p->details[i].drop;
}
fd = sd->fd;
WFIFOHEAD(fd,len+maxinfotype*szdetails);
WFIFOW(fd,0) = cmd;
for (i = 0; i < maxinfotype; i++) {
WFIFOB(fd,info->pos[4]+(i*szdetails)) = i; //infotype //0 PCRoom, 1 Premium, 2 Server, 3 TPlus
WFIFOL(fd,info->pos[5]+(i*szdetails)) = details_bexp[i]*factor;
WFIFOL(fd,info->pos[6]+(i*szdetails)) = details_penalty[i]*factor;
WFIFOL(fd,info->pos[7]+(i*szdetails)) = details_drop[i]*factor;
tot_baseexp += details_bexp[i]*factor;
tot_drop += details_drop[i]*factor;
tot_penalty += details_penalty[i]*factor;
len += szdetails;
}
WFIFOW(fd,info->pos[0]) = len; //packetlen
if (cmd == 0x08cb) { //0x08cb version
WFIFOW(fd,info->pos[1]) = tot_baseexp;
WFIFOW(fd,info->pos[2]) = tot_penalty;
WFIFOW(fd,info->pos[3]) = tot_drop;
}
else { //2013-08-07aRagexe uses 0x097b
WFIFOL(fd,info->pos[1]) = tot_baseexp;
WFIFOL(fd,info->pos[2]) = tot_penalty;
WFIFOL(fd,info->pos[3]) = tot_drop;
}
if (cmdtype == ZC_PERSONAL_INFOMATION_CHN)
WFIFOW(fd,info->pos[8]) = 0; //activity rate case of event ??
WFIFOSET(fd,len);
}
clif_send( p, p->length, &sd.bl, SELF );
#endif
}
#endif
@ -20134,46 +20049,36 @@ void clif_parse_GMFullStrip(int fd, struct map_session_data *sd) {
* @param fd
* @param bl Crimson Marker target
**/
void clif_crimson_marker(struct map_session_data *sd, struct block_list *bl, bool remove) {
struct s_packet_db* info;
int cmd = 0;
int16 len;
unsigned char buf[11];
void clif_crimson_marker( struct map_session_data& sd, struct block_list& bl, bool remove ){
#if PACKETVER_MAIN_NUM >= 20130731 || PACKETVER_RE_NUM >= 20130707 || defined(PACKETVER_ZERO)
struct PACKET_ZC_C_MARKERINFO p = {};
nullpo_retv(sd);
p.PacketType = HEADER_ZC_C_MARKERINFO;
p.AID = bl.id;
if( remove ){
p.xPos = -1;
p.yPos = -1;
}else{
p.xPos = bl.x;
p.yPos = bl.y;
}
cmd = packet_db_ack[ZC_C_MARKERINFO];
if (!cmd)
cmd = 0x09C1; //default
info = &packet_db[cmd];
if (!(len = info->len))
return;
WBUFW(buf, 0) = cmd;
WBUFL(buf, info->pos[0]) = bl->id;
WBUFW(buf, info->pos[1]) = (remove ? -1 : bl->x);
WBUFW(buf, info->pos[2]) = (remove ? -1 : bl->y);
clif_send(buf, len, &sd->bl, SELF);
clif_send( &p, sizeof( p ), &sd.bl, SELF );
#endif
}
/**
* 02d3 <index>.W (ZC_NOTIFY_BIND_ON_EQUIP)
**/
void clif_notify_bindOnEquip(struct map_session_data *sd, int n) {
struct s_packet_db *info = NULL;
int cmd = 0;
void clif_notify_bindOnEquip( struct map_session_data& sd, int16 index ){
#if PACKETVER >= 20070227
struct PACKET_ZC_NOTIFY_BIND_ON_EQUIP p = {};
nullpo_retv(sd);
p.packetType = HEADER_ZC_NOTIFY_BIND_ON_EQUIP;
p.index = client_index( index );
cmd = packet_db_ack[ZC_NOTIFY_BIND_ON_EQUIP];
info = &packet_db[cmd];
if (!cmd || !info->len)
return;
WFIFOHEAD(sd->fd, info->len);
WFIFOW(sd->fd, 0) = cmd;
WFIFOW(sd->fd, info->pos[0]) = n+2;
WFIFOSET(sd->fd, info->len);
clif_send( &p, sizeof( p ), &sd.bl, SELF );
#endif
}
/**
@ -20707,25 +20612,21 @@ void clif_parse_roulette_item( int fd, struct map_session_data* sd ){
* @param fd
* @param sd
**/
void clif_merge_item_ack(struct map_session_data *sd, unsigned short index, unsigned short count, enum MERGE_ITEM_ACK type) {
unsigned char buf[9];
struct s_packet_db *info = NULL;
short cmd = 0;
void clif_merge_item_ack( struct map_session_data &sd, enum MERGE_ITEM_ACK type, uint16 index = 0, uint16 count = 0 ){
#if PACKETVER_MAIN_NUM >= 20120314 || PACKETVER_RE_NUM >= 20120221 || defined(PACKETVER_ZERO)
struct PACKET_ZC_ACK_MERGE_ITEM p = {};
nullpo_retv(sd);
p.packetType = HEADER_ZC_ACK_MERGE_ITEM;
if( type == MERGE_ITEM_SUCCESS ){
p.index = client_index( index );
}else{
p.index = index;
}
p.amount = count;
p.reason = type;
if (!clif_session_isValid(sd))
return;
if (!(cmd = packet_db_ack[ZC_ACK_MERGE_ITEM]))
return;
if (!(info = &packet_db[cmd]) || info->len == 0)
return;
WBUFW(buf, 0) = cmd;
WBUFW(buf, info->pos[0]) = index;
WBUFW(buf, info->pos[1]) = count;
WBUFB(buf, info->pos[2]) = type;
clif_send(buf, info->len, &sd->bl, SELF);
clif_send( &p, sizeof( p ), &sd.bl, SELF );
#endif
}
/**
@ -20773,41 +20674,37 @@ static bool clif_merge_item_check(struct item_data *id, struct item *it) {
* ZC 096D <size>.W { <index>.W }* (ZC_MERGE_ITEM_OPEN)
* @param sd
**/
void clif_merge_item_open(struct map_session_data *sd) {
unsigned char buf[4 + MAX_INVENTORY*2] = { 0 };
unsigned short cmd = 0, n = 0, i = 0, indexes[MAX_INVENTORY] = { 0 };
int len = 0;
struct s_packet_db *info = NULL;
struct item *it;
void clif_merge_item_open( struct map_session_data& sd ){
#if PACKETVER_MAIN_NUM >= 20120314 || PACKETVER_RE_NUM >= 20120221 || defined(PACKETVER_ZERO)
struct PACKET_ZC_MERGE_ITEM_OPEN* p = (struct PACKET_ZC_MERGE_ITEM_OPEN*)packet_buffer;
nullpo_retv(sd);
if (!clif_session_isValid(sd))
return;
if (!(cmd = packet_db_ack[ZC_MERGE_ITEM_OPEN]))
return;
if (!(info = &packet_db[cmd]) || info->len == 0)
return;
p->packetType = HEADER_ZC_MERGE_ITEM_OPEN;
p->packetLen = sizeof( *p );
int n = 0;
// Get entries
for (i = 0; i < MAX_INVENTORY; i++) {
if (!clif_merge_item_check(sd->inventory_data[i], (it = &sd->inventory.u.items_inventory[i])))
for( int i = 0; i < MAX_INVENTORY; i++ ){
struct item* it = &sd.inventory.u.items_inventory[i];
if( !clif_merge_item_check( sd.inventory_data[i], it ) ){
continue;
if (clif_merge_item_has_pair(sd, it))
indexes[n++] = i;
}
if (n < 2) { // No item need to be merged
clif_msg(sd, MERGE_ITEM_NOT_AVAILABLE);
if( clif_merge_item_has_pair( &sd, it ) ){
p->items[n++].index = client_index( i );
p->packetLen += sizeof( p->items[0] );
}
}
// No item need to be merged
if( n < 2 ){
clif_msg( &sd, MERGE_ITEM_NOT_AVAILABLE );
return;
}
WBUFW(buf, 0) = cmd;
WBUFW(buf, info->pos[0]) = (len = 4 + n*2);
for (i = 0; i < n; i++) {
WBUFW(buf, info->pos[1] + i*2) = indexes[i]+2;
}
clif_send(buf, len, &sd->bl, SELF);
clif_send( p, p->packetLen, &sd.bl, SELF );
#endif
}
/**
@ -20846,7 +20743,7 @@ void clif_parse_merge_item_req(int fd, struct map_session_data* sd) {
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, 0, 0, MERGE_ITEM_FAILED_NOT_MERGE);
clif_merge_item_ack( *sd, MERGE_ITEM_FAILED_NOT_MERGE );
return;
}
count += sd->inventory.u.items_inventory[idx].amount;
@ -20859,7 +20756,7 @@ void clif_parse_merge_item_req(int fd, struct map_session_data* sd) {
}
if (count >= (id->stack.amount ? id->stack.amount : MAX_AMOUNT)) {
clif_merge_item_ack(sd, 0, 0, MERGE_ITEM_FAILED_MAX_COUNT);
clif_merge_item_ack( *sd, MERGE_ITEM_FAILED_MAX_COUNT );
return;
}
@ -20873,7 +20770,7 @@ void clif_parse_merge_item_req(int fd, struct map_session_data* sd) {
}
sd->inventory.u.items_inventory[indexes[0]].amount = count;
clif_merge_item_ack(sd, indexes[0]+2, count, MERGE_ITEM_SUCCESS);
clif_merge_item_ack( *sd, MERGE_ITEM_SUCCESS, indexes[0], count );
}
/**
@ -25126,7 +25023,6 @@ void packetdb_addpacket( uint16 cmd, uint16 length, void (*func)(int, struct map
*------------------------------------------*/
void packetdb_readdb(){
memset(packet_db,0,sizeof(packet_db));
memset(packet_db_ack,0,sizeof(packet_db_ack));
#include "clif_packetdb.hpp"
#include "clif_shuffle.hpp"

View File

@ -59,25 +59,6 @@ enum e_PacketDBVersion { // packet DB
#endif
};
enum e_packet_ack : uint8_t{
ZC_ACK_OPEN_BANKING = 0,
ZC_ACK_CLOSE_BANKING,
ZC_ACK_BANKING_DEPOSIT,
ZC_ACK_BANKING_WITHDRAW,
ZC_BANKING_CHECK,
ZC_PERSONAL_INFOMATION,
ZC_PERSONAL_INFOMATION_CHN,
ZC_CLEAR_DIALOG,
ZC_C_MARKERINFO,
ZC_NOTIFY_BIND_ON_EQUIP,
ZC_WEAR_EQUIP_ACK,
ZC_MERGE_ITEM_OPEN,
ZC_ACK_MERGE_ITEM,
ZC_BROADCASTING_SPECIAL_ITEM_OBTAIN,
//add other here
MAX_ACK_FUNC //auto upd len
};
struct s_packet_db {
short len;
void (*func)(int, struct map_session_data *);
@ -214,7 +195,6 @@ enum class e_purchase_result : uint8{
#define packet_len(cmd) packet_db[cmd].len
extern struct s_packet_db packet_db[MAX_PACKET_DB+1];
extern int packet_db_ack[MAX_ACK_FUNC + 1];
// local define
enum send_target : uint8_t {
@ -516,9 +496,15 @@ enum clif_messages : uint16_t {
ADDITEM_TO_CART_FAIL_COUNT = 0x1,
// clif_equipitemack flags
#if PACKETVER_MAIN_NUM >= 20121205 || PACKETVER_RE_NUM >= 20121107 || defined(PACKETVER_ZERO)
ITEM_EQUIP_ACK_OK = 0,
ITEM_EQUIP_ACK_FAIL = 1,
ITEM_EQUIP_ACK_FAILLEVEL = 2,
ITEM_EQUIP_ACK_FAIL = 2,
ITEM_EQUIP_ACK_FAILLEVEL = 1,
#else
ITEM_EQUIP_ACK_OK = 1,
ITEM_EQUIP_ACK_FAIL = 0,
ITEM_EQUIP_ACK_FAILLEVEL = 0,
#endif
/* -end- */
//! NOTE: These values below need client version validation
@ -645,7 +631,7 @@ void clif_parse_NPCMarketPurchase(int fd, struct map_session_data *sd);
void clif_scriptmes( struct map_session_data& sd, uint32 npcid, const char *mes );
void clif_scriptnext( struct map_session_data& sd, uint32 npcid );
void clif_scriptclose(struct map_session_data *sd, int npcid); //self
void clif_scriptclear(struct map_session_data *sd, int npcid); //self
void clif_scriptclear( struct map_session_data& sd, int npcid ); //self
void clif_scriptmenu(struct map_session_data* sd, int npcid, const char* mes); //self
void clif_scriptinput(struct map_session_data *sd, int npcid); //self
void clif_scriptinputstr(struct map_session_data *sd, int npcid); // self
@ -669,7 +655,7 @@ void clif_arrowequip(struct map_session_data *sd,int val); //self
void clif_arrow_fail(struct map_session_data *sd,int type); //self
void clif_arrow_create_list(struct map_session_data *sd); //self
void clif_statusupack(struct map_session_data *sd,int type,int ok,int val); // self
void clif_equipitemack(struct map_session_data *sd,int n,int pos,uint8 flag); // self
void clif_equipitemack( struct map_session_data& sd, uint8 flag, int index, int pos = 0 ); // self
void clif_unequipitemack(struct map_session_data *sd,int n,int pos,int ok); // self
void clif_misceffect(struct block_list* bl,int type); // area
void clif_changeoption_target(struct block_list* bl, struct block_list* target);
@ -1042,8 +1028,6 @@ void clif_PartyBookingDeleteNotify(struct map_session_data* sd, int index);
void clif_PartyBookingInsertNotify(struct map_session_data* sd, struct party_booking_ad_info* pb_ad);
/* Bank System [Yommy/Hercules] */
void clif_bank_deposit (struct map_session_data *sd, enum e_BANKING_DEPOSIT_ACK reason);
void clif_bank_withdraw (struct map_session_data *sd,enum e_BANKING_WITHDRAW_ACK reason);
void clif_parse_BankDeposit (int fd, struct map_session_data *sd);
void clif_parse_BankWithdraw (int fd, struct map_session_data *sd);
void clif_parse_BankCheck (int fd, struct map_session_data *sd);
@ -1074,7 +1058,7 @@ void clif_search_store_info_click_ack(struct map_session_data* sd, short x, shor
void clif_cashshop_result( struct map_session_data* sd, t_itemid item_id, uint16 result );
void clif_cashshop_open( struct map_session_data* sd, int tab );
void clif_display_pinfo(struct map_session_data *sd, int type);
void clif_display_pinfo( struct map_session_data& sd );
/// Roulette
void clif_roulette_open(struct map_session_data* sd);
@ -1140,15 +1124,15 @@ void clif_channel_msg(struct Channel *channel, const char *msg, unsigned long co
void clif_ranklist(struct map_session_data *sd, int16 rankingType);
void clif_update_rankingpoint(map_session_data &sd, int rankingtype, int point);
void clif_crimson_marker(struct map_session_data *sd, struct block_list *bl, bool remove);
void clif_crimson_marker( struct map_session_data& sd, struct block_list& bl, bool remove );
void clif_showscript(struct block_list* bl, const char* message, enum send_target flag);
void clif_party_leaderchanged(struct map_session_data *sd, int prev_leader_aid, int new_leader_aid);
void clif_account_name(int fd, uint32 account_id, const char* accname);
void clif_notify_bindOnEquip(struct map_session_data *sd, int n);
void clif_notify_bindOnEquip( struct map_session_data& sd, int16 index );
void clif_merge_item_open(struct map_session_data *sd);
void clif_merge_item_open( struct map_session_data& sd );
void clif_broadcast_obtain_special_item(const char *char_name, t_itemid nameid, t_itemid container, enum BROADCASTING_SPECIAL_ITEM_OBTAIN type);

View File

@ -6,9 +6,6 @@
#define packet(cmd,length) packetdb_addpacket(cmd,length,NULL,0)
#define parseable_packet(cmd,length,func,...) packetdb_addpacket(cmd,length,func,__VA_ARGS__,0)
#define ack_packet(type,cmd,length,...) \
packetdb_addpacket(cmd,length,NULL,__VA_ARGS__,0); \
packet_db_ack[type] = cmd
packet(0x0064,55);
packet(0x0065,17);
@ -78,7 +75,6 @@
parseable_packet(0x00a7,8,clif_parse_UseItem,2,4);
packet( useItemAckType, sizeof( struct PACKET_ZC_USE_ITEM_ACK ) );
parseable_packet(0x00a9,6,clif_parse_EquipItem,2,4);
ack_packet(ZC_WEAR_EQUIP_ACK,0x00aa,7,2,4,6);
parseable_packet(0x00ab,4,clif_parse_UnequipItem,2);
packet(0x00ac,7);
//packet(0x00ad,-1);
@ -415,7 +411,6 @@
//packet(0x020c,-1);
packet(0x020d,-1);
packet(0x8b3,-1);
ack_packet(ZC_CLEAR_DIALOG,0x8d6,6,2);
// 2004-07-05aSakexe
#if PACKETVER >= 20040705
@ -1082,7 +1077,6 @@
packet(0x02cd,26);
packet(0x02ce,10);
parseable_packet(0x02cf,6,clif_parse_MemorialDungeonCommand,2);
ack_packet(ZC_NOTIFY_BIND_ON_EQUIP,0x02d3,4,2);
packet(0x02d5,2);
parseable_packet(0x02d6,6,clif_parse_ViewPlayerEquip,2);
parseable_packet(0x02d8,10,clif_parse_configuration,2,6);
@ -1582,7 +1576,6 @@
// 2009-12-01aRagexeRE
#if PACKETVER >= 20091201
packet(0x07fc,10);
ack_packet(ZC_BROADCASTING_SPECIAL_ITEM_OBTAIN,0x07fd,-1,0);
//packet(0x07ff,-1);
#endif
@ -1720,7 +1713,6 @@
// 2010-06-29aRagexeRE
#if PACKETVER >= 20100629
ack_packet(ZC_WEAR_EQUIP_ACK,0x00AA,9,2,4,6,8);
//packet(0x07F1,18);
//packet(0x07F2,8);
//packet(0x07F3,6);
@ -1773,7 +1765,6 @@
packet(0x0856,-1);
packet(0x0857,-1);
packet(0x0858,-1);
ack_packet(ZC_WEAR_EQUIP_ACK,0x08d0,9,2,4,6,8);
#endif
// 2011-10-05aRagexeRE
@ -1924,11 +1915,8 @@
packet(0x0977,14); //Monster HP Bar
parseable_packet(0x0916,26,clif_parse_GuildInvite2,2);
parseable_packet(0x091d,41,clif_parse_PartyBookingRegisterReq,2,4,6);
ack_packet(ZC_PERSONAL_INFOMATION,0x08cb,10,2,4,6,8,10,11,13,15); //Still need further information
// Merge Item
ack_packet(ZC_MERGE_ITEM_OPEN,0x096D,-1,2,4); // ZC_MERGE_ITEM_OPEN
parseable_packet(0x096E,-1,clif_parse_merge_item_req,2,4); // CZ_REQ_MERGE_ITEM
ack_packet(ZC_ACK_MERGE_ITEM,0x096F,7,2,4,6); // ZC_ACK_MERGE_ITEM
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
@ -2033,10 +2021,7 @@
packet(0x0977,14); //Monster HP Bar
parseable_packet(0x0978,6,clif_parse_reqworldinfo,2);
packet(0x0979,50); //ackworldinfo
ack_packet(ZC_PERSONAL_INFOMATION,0x097b,16,2,4,8,12,16,17,21,25); //Still need further information
//ack_packet(ZC_PERSONAL_INFOMATION_CHN,0x0981,12,2,4,6,8,12,13,15,17,10); // Disabled until further information is found.
parseable_packet(0x0998,8,clif_parse_EquipItem,2,4); // CZ_REQ_WEAR_EQUIP_V5
ack_packet(ZC_WEAR_EQUIP_ACK,0x0999,11,2,4,8,10); // cz_wear_equipv5
packet(0x099a,9); // take_off_equipv5
packet(0x099b,8); //maptypeproperty2
// New Packets
@ -2060,16 +2045,11 @@
// 2013-07-17Ragexe
#if PACKETVER >= 20130717
ack_packet(ZC_BANKING_CHECK,0x09A6,12,2,10);
parseable_packet(0x09A7,10,clif_parse_BankDeposit,2,6);
ack_packet(ZC_ACK_BANKING_DEPOSIT,0x09A8,16,2,4,12);
parseable_packet(0x09A9,10,clif_parse_BankWithdraw,2,6);
ack_packet(ZC_ACK_BANKING_WITHDRAW,0x09AA,16,2,4,12);
parseable_packet(0x09AB,6,clif_parse_BankCheck,2);
parseable_packet(0x09B6,6,clif_parse_BankOpen,2);
ack_packet(ZC_ACK_OPEN_BANKING,0x09B7,4,2);
parseable_packet(0x09B8,6,clif_parse_BankClose,2);
ack_packet(ZC_ACK_CLOSE_BANKING,0x09B9,4,2);
#endif
// 2013-07-31cRagexe
@ -2080,11 +2060,8 @@
// 2013-08-07Ragexe
#if PACKETVER >= 20130807
ack_packet(ZC_C_MARKERINFO,0x09C1,10,2,6,8);
// Merge Item
ack_packet(ZC_MERGE_ITEM_OPEN,0x096D,-1,2,4); // ZC_MERGE_ITEM_OPEN
parseable_packet(0x096E,-1,clif_parse_merge_item_req,2,4); // CZ_REQ_MERGE_ITEM
ack_packet(ZC_ACK_MERGE_ITEM,0x096F,7,2,4,6,7); // ZC_ACK_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

@ -5,6 +5,8 @@
#include <iostream>
#include <stdlib.h>
#include <math.h>
#include <unordered_map>
#include "../common/nullpo.hpp"
#include "../common/random.hpp"
@ -1239,6 +1241,98 @@ std::shared_ptr<item_data> ItemDatabase::searchname( const char *name ){
return util::umap_find( this->nameToItemDataMap, lowername );
}
/**
* Generates an item link string
* @param data: Item info
* @return <ITEML> string for the item
* @author [Cydh]
**/
std::string ItemDatabase::create_item_link( struct item& item ){
std::shared_ptr<item_data> data = this->find( item.nameid );
if( data == nullptr ){
ShowError( "Tried to create itemlink for unknown item %u.\n", item.nameid );
return "Unknown item";
}
// All these dates are unconfirmed
#if PACKETVER >= 20100000
if( !battle_config.feature_itemlink ){
// Feature is disabled
return data->ename;
}
struct item_data* id = data.get();
#if PACKETVER_MAIN_NUM >= 20200916 || PACKETVER_RE_NUM >= 20200724
const std::string start_tag = "<ITEML>";
const std::string closing_tag = "</ITEML>";
#else // PACKETVER >= 20100000
const std::string start_tag = "<ITEMLINK>";
const std::string closing_tag = "</ITEMLINK>";
#endif
std::string itemstr = start_tag;
itemstr += util::string_left_pad(util::base62_encode(id->equip), '0', 5);
itemstr += itemdb_isequip2(id) ? "1" : "0";
itemstr += util::base62_encode(item.nameid);
if (item.refine > 0) {
itemstr += "%" + util::string_left_pad(util::base62_encode(item.refine), '0', 2);
}
if (itemdb_isequip2(id)) {
itemstr += "&" + util::string_left_pad(util::base62_encode(id->look), '0', 2);
}
#if PACKETVER_MAIN_NUM >= 20200916 || PACKETVER_RE_NUM >= 20200724
itemstr += "'" + util::string_left_pad(util::base62_encode(item.enchantgrade), '0', 2);
#endif
#if PACKETVER_MAIN_NUM >= 20200916 || PACKETVER_RE_NUM >= 20200724
const std::string card_sep = ")";
const std::string optid_sep = "+";
const std::string optpar_sep = ",";
const std::string optval_sep = "-";
#else
const std::string card_sep = "(";
const std::string optid_sep = "*";
const std::string optpar_sep = "+";
const std::string optval_sep = ",";
#endif
for (uint8 i = 0; i < MAX_SLOTS; ++i) {
itemstr += card_sep + util::string_left_pad(util::base62_encode(item.card[i]), '0', 2);
}
#if PACKETVER >= 20150225
for (uint8 i = 0; i < MAX_ITEM_RDM_OPT; ++i) {
if (item.option[i].id == 0) {
break; // ignore options including ones beyond this one since the client won't even display them
}
// Option ID
itemstr += optid_sep + util::string_left_pad(util::base62_encode(item.option[i].id), '0', 2);
// Param
itemstr += optpar_sep + util::string_left_pad(util::base62_encode(item.option[i].param), '0', 2);
// Value
itemstr += optval_sep + util::string_left_pad(util::base62_encode(item.option[i].value), '0', 2);
}
#endif
itemstr += closing_tag;
return itemstr;
#else
// Did not exist before that
return data->ename;
#endif
}
std::string ItemDatabase::create_item_link( t_itemid id ){
struct item it = {};
it.nameid = id;
return this->create_item_link( it );
}
ItemDatabase item_db;
/**

View File

@ -5,6 +5,7 @@
#define ITEMDB_HPP
#include <map>
#include <string>
#include <vector>
#include "../common/database.hpp"
@ -1344,6 +1345,8 @@ public:
// Additional
std::shared_ptr<item_data> searchname( const char* name );
std::shared_ptr<item_data> search_aegisname( const char *name );
std::string create_item_link( struct item& data );
std::string create_item_link( t_itemid id );
};
extern ItemDatabase item_db;

View File

@ -645,12 +645,13 @@ enum e_mapflag : int16 {
MF_PRIVATEAIRSHIP_SOURCE,
MF_PRIVATEAIRSHIP_DESTINATION,
MF_SKILL_DURATION,
MF_NOCASHSHOP,
MF_NOCASHSHOP, // 70
MF_NORODEX,
MF_NORENEWALEXPPENALTY,
MF_NORENEWALDROPPENALTY,
MF_NOPETCAPTURE,
MF_NOBUYINGSTORE,
MF_NODYNAMICNPC,
MF_MAX
};

View File

@ -2286,6 +2286,8 @@ bool npc_scriptcont(struct map_session_data* sd, int id, bool closing){
// close
case CLOSE:
sd->st->state = END;
if (sd->st->clear_cutin)
clif_cutin(sd,"",255);
break;
// close2
case STOP:
@ -5805,7 +5807,10 @@ struct npc_data* npc_duplicate_npc_for_player( struct npc_data& nd, struct map_s
return nullptr;
}
// TODO: check maps that might forbid usage? maybe create mapflag?
if( map_getmapflag( sd.bl.m, MF_NODYNAMICNPC ) ){
// It has been confirmed that there is no reply to the client
return nullptr;
}
int16 new_x, new_y;

View File

@ -367,6 +367,46 @@ struct PACKET_CZ_REQ_CHANGE_MEMBERPOS{
struct PACKET_CZ_REQ_CHANGE_MEMBERPOS_sub list[];
} __attribute__((packed));
struct PACKET_ZC_CLEAR_DIALOG{
int16 packetType;
uint32 GID;
} __attribute__((packed));
struct PACKET_ZC_NOTIFY_BIND_ON_EQUIP{
int16 packetType;
int16 index;
} __attribute__((packed));
struct PACKET_ZC_BANKING_CHECK{
int16 packetType;
int64 money;
int16 reason;
} __attribute__((packed));
struct PACKET_ZC_ACK_BANKING_WITHDRAW{
int16 packetType;
int16 reason;
int64 money;
int32 zeny;
} __attribute__((packed));
struct PACKET_ZC_ACK_BANKING_DEPOSIT{
int16 packetType;
int16 reason;
int64 money;
int32 zeny;
} __attribute__((packed));
struct PACKET_ZC_ACK_CLOSE_BANKING{
int16 packetType;
int16 unknown;
} __attribute__((packed));
struct PACKET_ZC_ACK_OPEN_BANKING{
int16 packetType;
int16 unknown;
} __attribute__((packed));
#if PACKETVER_MAIN_NUM >= 20140508 || PACKETVER_RE_NUM >= 20140508 || defined(PACKETVER_ZERO)
struct PACKET_ZC_GOLDPCCAFE_POINT{
int16 packetType;
@ -415,15 +455,22 @@ DEFINE_PACKET_HEADER(ZC_ACK_WEAPONREFINE, 0x223)
DEFINE_PACKET_HEADER(CZ_REQ_MAKINGITEM, 0x25b)
DEFINE_PACKET_HEADER(ZC_CASH_TIME_COUNTER, 0x298)
DEFINE_PACKET_HEADER(ZC_CASH_ITEM_DELETE, 0x299)
DEFINE_PACKET_HEADER(ZC_NOTIFY_BIND_ON_EQUIP, 0x2d3)
DEFINE_PACKET_HEADER(ZC_FAILED_TRADE_BUYING_STORE_TO_SELLER, 0x824)
DEFINE_PACKET_HEADER(CZ_SSILIST_ITEM_CLICK, 0x83c)
DEFINE_PACKET_HEADER(ZC_CLEAR_DIALOG, 0x8d6)
DEFINE_PACKET_HEADER(ZC_ENTRY_QUEUE_INIT, 0x90e);
DEFINE_PACKET_HEADER(ZC_BANKING_CHECK, 0x9a6)
DEFINE_PACKET_HEADER(ZC_ACK_BANKING_DEPOSIT, 0x9a8)
DEFINE_PACKET_HEADER(ZC_ACK_BANKING_WITHDRAW, 0x9aa)
DEFINE_PACKET_HEADER(CZ_REQ_CASH_BARGAIN_SALE_ITEM_INFO, 0x9ac)
DEFINE_PACKET_HEADER(ZC_ACK_CASH_BARGAIN_SALE_ITEM_INFO, 0x9ad)
DEFINE_PACKET_HEADER(CZ_REQ_APPLY_BARGAIN_SALE_ITEM, 0x9ae)
DEFINE_PACKET_HEADER(CZ_REQ_REMOVE_BARGAIN_SALE_ITEM, 0x9b0)
DEFINE_PACKET_HEADER(ZC_NOTIFY_BARGAIN_SALE_SELLING, 0x9b2)
DEFINE_PACKET_HEADER(ZC_NOTIFY_BARGAIN_SALE_CLOSE, 0x9b3)
DEFINE_PACKET_HEADER(ZC_ACK_OPEN_BANKING, 0x9b7)
DEFINE_PACKET_HEADER(ZC_ACK_CLOSE_BANKING, 0x9b9)
DEFINE_PACKET_HEADER(ZC_ACK_COUNT_BARGAIN_SALE_ITEM, 0x9c4)
DEFINE_PACKET_HEADER(ZC_ACK_GUILDSTORAGE_LOG, 0x9da)
DEFINE_PACKET_HEADER(ZC_GOLDPCCAFE_POINT, 0xa15)

View File

@ -4704,7 +4704,23 @@ struct PACKET_ZC_PERSONAL_INFOMATION {
struct PACKET_ZC_PERSONAL_INFOMATION_SUB details[];
} __attribute__((packed));
DEFINE_PACKET_HEADER(ZC_PERSONAL_INFOMATION, 0x097b);
#endif // PACKETVER_MAIN_NUM >= 20120503 || PACKETVER_RE_NUM >= 20120502 || defined(PACKETVER_ZERO)
#elif PACKETVER_MAIN_NUM >= 20110627 || PACKETVER_RE_NUM >= 20110628
struct PACKET_ZC_PERSONAL_INFOMATION_SUB {
int8 type;
int16 exp;
int16 death;
int16 drop;
} __attribute__((packed));
struct PACKET_ZC_PERSONAL_INFOMATION {
int16 packetType;
int16 length;
int16 total_exp;
int16 total_death;
int16 total_drop;
struct PACKET_ZC_PERSONAL_INFOMATION_SUB details[];
} __attribute__((packed));
DEFINE_PACKET_HEADER(ZC_PERSONAL_INFOMATION, 0x08cb);
#endif // PACKETVER_MAIN_NUM >= 20110627 || PACKETVER_RE_NUM >= 20110628
struct PACKET_CZ_REQUEST_ACTNPC {
int16 packetType;

View File

@ -9308,7 +9308,7 @@ void pc_close_npc(struct map_session_data *sd,int flag)
if (sd->st) {
if (sd->st->state == CLOSE) {
clif_scriptclose(sd, sd->npc_id);
clif_scriptclear(sd, sd->npc_id); // [Ind/Hercules]
clif_scriptclear( *sd, sd->npc_id ); // [Ind/Hercules]
sd->st->state = END; // Force to end now
}
if (sd->st->state == END) { // free attached scripts that are waiting
@ -11562,7 +11562,8 @@ bool pc_equipitem(struct map_session_data *sd,short n,int req_pos,bool equipswit
if( equipswitch ){
clif_equipswitch_add( sd, n, req_pos, ITEM_EQUIP_ACK_FAIL );
}else{
clif_equipitemack(sd,0,0,ITEM_EQUIP_ACK_FAIL);
// Does not deserve an answer... [Lemongrass]
//clif_equipitemack( sd, ITEM_EQUIP_ACK_FAIL, n );
}
return false;
}
@ -11570,7 +11571,7 @@ bool pc_equipitem(struct map_session_data *sd,short n,int req_pos,bool equipswit
if( equipswitch ){
clif_equipswitch_add( sd, n, req_pos, ITEM_EQUIP_ACK_FAIL );
}else{
clif_equipitemack(sd,n,0,ITEM_EQUIP_ACK_FAIL);
clif_equipitemack( *sd, ITEM_EQUIP_ACK_FAIL, n );
}
return false;
}
@ -11586,7 +11587,7 @@ bool pc_equipitem(struct map_session_data *sd,short n,int req_pos,bool equipswit
if( equipswitch ){
clif_equipswitch_add( sd, n, req_pos, res );
}else{
clif_equipitemack(sd,n,0,res); // fail
clif_equipitemack( *sd, res, n ); // fail
}
return false;
}
@ -11600,7 +11601,7 @@ bool pc_equipitem(struct map_session_data *sd,short n,int req_pos,bool equipswit
if( equipswitch ){
clif_equipswitch_add( sd, n, req_pos, ITEM_EQUIP_ACK_FAIL );
}else{
clif_equipitemack(sd,n,0,ITEM_EQUIP_ACK_FAIL); // fail
clif_equipitemack( *sd, ITEM_EQUIP_ACK_FAIL, n ); // fail
}
return false;
}
@ -11608,7 +11609,7 @@ bool pc_equipitem(struct map_session_data *sd,short n,int req_pos,bool equipswit
if( equipswitch ){
clif_equipswitch_add( sd, n, req_pos, ITEM_EQUIP_ACK_FAIL );
}else{
clif_equipitemack(sd,n,0,ITEM_EQUIP_ACK_FAIL); //Fail
clif_equipitemack( *sd, ITEM_EQUIP_ACK_FAIL, n ); //Fail
}
return false;
}
@ -11617,7 +11618,7 @@ bool pc_equipitem(struct map_session_data *sd,short n,int req_pos,bool equipswit
if ( !equipswitch && id->flag.bindOnEquip && !sd->inventory.u.items_inventory[n].bound) {
sd->inventory.u.items_inventory[n].bound = (char)battle_config.default_bind_on_equip;
clif_notify_bindOnEquip(sd,n);
clif_notify_bindOnEquip( *sd, n );
}
if(pos == EQP_ACC) { //Accessories should only go in one of the two.
@ -11700,7 +11701,7 @@ bool pc_equipitem(struct map_session_data *sd,short n,int req_pos,bool equipswit
clif_arrow_fail(sd,3);
}
else
clif_equipitemack(sd,n,pos,ITEM_EQUIP_ACK_OK);
clif_equipitemack( *sd, ITEM_EQUIP_ACK_OK, n, pos );
sd->inventory.u.items_inventory[n].equip = pos;
}
@ -14244,7 +14245,7 @@ void pc_scdata_received(struct map_session_data *sd) {
clif_weight_limit( sd );
if( pc_has_permission( sd, PC_PERM_ATTENDANCE ) && pc_attendance_enabled() && !pc_attendance_rewarded_today( sd ) ){
if( pc_has_permission( sd, PC_PERM_ATTENDANCE ) && pc_attendance_enabled() && !pc_attendance_rewarded_today( sd ) && pc_attendance_counter(sd) < 200 ){
clif_ui_open( *sd, OUT_UI_ATTENDANCE, pc_attendance_counter( sd ) );
}

View File

@ -1514,7 +1514,7 @@ int pet_equipitem(struct map_session_data *sd,int index)
t_itemid nameid = sd->inventory.u.items_inventory[index].nameid;
if(pet_db_ptr->AcceID == 0 || nameid != pet_db_ptr->AcceID || pd->pet.equip != 0) {
clif_equipitemack(sd,0,0,ITEM_EQUIP_ACK_FAIL);
clif_equipitemack( *sd, ITEM_EQUIP_ACK_FAIL, index );
return 1;
}

View File

@ -4967,7 +4967,7 @@ BUILDIN_FUNC(clear)
if (!script_rid2sd(sd))
return SCRIPT_CMD_FAILURE;
clif_scriptclear(sd, st->oid);
clif_scriptclear( *sd, st->oid );
return SCRIPT_CMD_SUCCESS;
}
@ -4977,20 +4977,26 @@ BUILDIN_FUNC(clear)
/// close;
BUILDIN_FUNC(close)
{
TBL_PC* sd;
struct map_session_data* sd;
if( !script_rid2sd(sd) )
return SCRIPT_CMD_SUCCESS;
const char* command = script_getfuncname( st );
if( !st->mes_active ) {
st->state = END; // Keep backwards compatibility.
ShowWarning("Incorrect use of 'close' command!\n");
ShowWarning("buildin_close: Incorrect use of '%s' command!\n", command);
script_reportsrc(st);
} else {
st->state = CLOSE;
st->mes_active = 0;
}
if( !strcmp(command, "close3") ){
st->clear_cutin = true;
}
clif_scriptclose(sd, st->oid);
return SCRIPT_CMD_SUCCESS;
}
@ -18406,58 +18412,48 @@ BUILDIN_FUNC(checkidlemer)
BUILDIN_FUNC(searchitem)
{
struct script_data* data = script_getdata(st, 2);
const char *itemname = script_getstr(st,3);
std::map<t_itemid, std::shared_ptr<item_data>> items;
int count;
char* name;
int32 start;
int32 id;
int32 i;
TBL_PC* sd = NULL;
if ((items[0] = item_db.find(strtoul(itemname, nullptr, 10))))
count = 1;
else
count = itemdb_searchname_array(items, MAX_SEARCH, itemname);
if (!count) {
script_pushint(st, 0);
return SCRIPT_CMD_SUCCESS;
}
script_data* data = script_getdata(st, 2);
const char *name = reference_getname(data);
if( !data_isreference(data) )
{
ShowError("script:searchitem: not a variable\n");
ShowError("buildin_searchitem: Argument %s is not a variable.\n", name);
script_reportdata(data);
st->state = END;
return SCRIPT_CMD_FAILURE;// not a variable
}
id = reference_getid(data);
start = reference_getindex(data);
name = reference_getname(data);
if( is_string_variable(name) )
{// string array
ShowError("buildin_searchitem: Argument %s is not an integer array.\n", name);
script_reportdata(data);
st->state = END;
return SCRIPT_CMD_FAILURE;// not supported
}
map_session_data *sd = nullptr;
if (not_server_variable(*name) && !script_rid2sd(sd))
{
return SCRIPT_CMD_SUCCESS;// no player attached
}
if( is_string_variable(name) )
{// string array
ShowError("script:searchitem: not an integer array reference\n");
script_reportdata(data);
st->state = END;
return SCRIPT_CMD_FAILURE;// not supported
const char *itemname = script_getstr(st, 3);
std::map<t_itemid, std::shared_ptr<item_data>> items;
itemdb_searchname_array(items, MAX_SEARCH, itemname);
if (!items.empty()) {
int32 id = reference_getid(data);
int32 start = reference_getindex(data);
for (const auto &it : items) { // Set array
set_reg_num(st, sd, reference_uid(id, start), name, it.first, reference_getref(data));
start++;
}
}
for( i = 0; i < count; ++start, ++i )
{// Set array
set_reg_num( st, sd, reference_uid( id, start ), name, items[i]->nameid, reference_getref( data ) );
}
script_pushint(st, count);
script_pushint64(st, items.size());
return SCRIPT_CMD_SUCCESS;
}
@ -19872,29 +19868,6 @@ BUILDIN_FUNC(unittalk)
return SCRIPT_CMD_SUCCESS;
}
/// Makes the unit do an emotion.
///
/// unitemote <unit_id>,<emotion>;
///
/// @see ET_* in script_constants.hpp
BUILDIN_FUNC(unitemote)
{
int emotion;
struct block_list* bl;
emotion = script_getnum(st,3);
if (emotion < ET_SURPRISE || emotion >= ET_MAX) {
ShowWarning("buildin_emotion: Unknown emotion %d (min=%d, max=%d).\n", emotion, ET_SURPRISE, (ET_MAX-1));
return SCRIPT_CMD_FAILURE;
}
if (script_rid2bl(2,bl))
clif_emotion(bl, emotion);
return SCRIPT_CMD_SUCCESS;
}
/// Makes the unit cast the skill on the target or self if no target is specified.
///
/// unitskilluseid <unit_id>,<skill_id>,<skill_lv>{,<target_id>,<casttime>,<cancel>,<Line_ID>};
@ -23633,7 +23606,7 @@ BUILDIN_FUNC(mergeitem) {
if (!script_charid2sd(2, sd))
return SCRIPT_CMD_FAILURE;
clif_merge_item_open(sd);
clif_merge_item_open( *sd );
return SCRIPT_CMD_SUCCESS;
}
@ -25230,7 +25203,7 @@ BUILDIN_FUNC(duplicate_dynamic){
if( dnd == nullptr ){
script_pushstrcopy( st, "" );
return SCRIPT_CMD_FAILURE;
return SCRIPT_CMD_SUCCESS;
}else{
script_pushstrcopy( st, dnd->exname );
return SCRIPT_CMD_SUCCESS;
@ -26774,6 +26747,41 @@ BUILDIN_FUNC(item_enchant){
#endif
}
/**
* Generate item link string for client
* itemlink(<item_id>,<refine>,<card0>,<card1>,<card2>,<card3>,<enchantgrade>{,<RandomIDArray>,<RandomValueArray>,<RandomParamArray>});
* @author [Cydh]
**/
BUILDIN_FUNC(itemlink)
{
struct item item = {};
item.nameid = script_getnum(st, 2);
if( !item_db.exists( item.nameid ) ){
ShowError( "buildin_itemlink: Item ID %u does not exists.\n", item.nameid );
st->state = END;
return SCRIPT_CMD_FAILURE;
}
FETCH(3, item.refine);
FETCH(4, item.card[0]);
FETCH(5, item.card[1]);
FETCH(6, item.card[2]);
FETCH(7, item.card[3]);
FETCH(8, item.enchantgrade);
#if PACKETVER >= 20150225
if ( script_hasdata(st,9) && script_getitem_randomoption(st, nullptr, &item, "itemlink", 9) == false) {
st->state = END;
return SCRIPT_CMD_FAILURE;
}
#endif
std::string itemlstr = item_db.create_item_link(item);
script_pushstrcopy(st, itemlstr.c_str());
return SCRIPT_CMD_SUCCESS;
}
BUILDIN_FUNC(addfame) {
struct map_session_data *sd;
@ -26810,6 +26818,17 @@ BUILDIN_FUNC(getfamerank) {
return SCRIPT_CMD_SUCCESS;
}
BUILDIN_FUNC(isdead) {
struct map_session_data *sd;
if (!script_mapid2sd(2, sd))
return SCRIPT_CMD_FAILURE;
script_pushint(st, pc_isdead(sd));
return SCRIPT_CMD_SUCCESS;
}
#include "../custom/script.inc"
// declarations that were supposed to be exported from npc_chat.cpp
@ -26867,6 +26886,7 @@ struct script_function buildin_func[] = {
BUILDIN_DEF(clear,""),
BUILDIN_DEF(close,""),
BUILDIN_DEF(close2,""),
BUILDIN_DEF2(close, "close3", ""),
BUILDIN_DEF(menu,"sl*"),
BUILDIN_DEF(select,"s*"), //for future jA script compatibility
BUILDIN_DEF(prompt,"s*"),
@ -27277,7 +27297,6 @@ struct script_function buildin_func[] = {
BUILDIN_DEF(unitstopattack,"i"),
BUILDIN_DEF(unitstopwalk,"i?"),
BUILDIN_DEF(unittalk,"is?"),
BUILDIN_DEF_DEPRECATED(unitemote,"ii","20170811"),
BUILDIN_DEF(unitskilluseid,"ivi????"), // originally by Qamera [Celest]
BUILDIN_DEF(unitskillusepos,"iviii???"), // [Celest]
// <--- [zBuffer] List of unit control commands
@ -27558,9 +27577,11 @@ struct script_function buildin_func[] = {
BUILDIN_DEF(add_reputation_points, "ii?"),
BUILDIN_DEF(item_reform, "??"),
BUILDIN_DEF(item_enchant, "i?"),
BUILDIN_DEF(itemlink, "i?????????"),
BUILDIN_DEF(addfame, "i?"),
BUILDIN_DEF(getfame, "?"),
BUILDIN_DEF(getfamerank, "?"),
BUILDIN_DEF(isdead, "?"),
#include "../custom/script_def.inc"
{NULL,NULL,NULL},

View File

@ -328,6 +328,7 @@ struct script_state {
unsigned op2ref : 1;// used by op_2
unsigned npc_item_flag : 1;
unsigned mes_active : 1; // Store if invoking character has a NPC dialog box open.
unsigned clear_cutin : 1;
char* funcname; // Stores the current running function name
unsigned int id;
};

View File

@ -536,6 +536,7 @@
export_constant(MF_NORENEWALEXPPENALTY);
export_constant(MF_NOPETCAPTURE);
export_constant(MF_NOBUYINGSTORE);
export_constant(MF_NODYNAMICNPC);
/* setcell types */
export_constant(CELL_WALKABLE);

View File

@ -12815,8 +12815,9 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
break;
case SC_C_MARKER:
//Send mini-map, don't wait for first timer triggered
if (src->type == BL_PC && (sd = map_id2sd(src->id)))
clif_crimson_marker(sd, bl, false);
if (src->type == BL_PC) {
clif_crimson_marker(*(struct map_session_data *)(src), *bl, false);
}
break;
case SC_ITEMSCRIPT: // Shows Buff Icons
if (sd)
@ -13419,7 +13420,7 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
ARR_FIND(0,MAX_SKILL_CRIMSON_MARKER,i,caster->c_marker[i] == bl->id);
if (i < MAX_SKILL_CRIMSON_MARKER) {
caster->c_marker[i] = 0;
clif_crimson_marker(caster, bl, true);
clif_crimson_marker( *caster, *bl, true );
}
}
break;
@ -14417,7 +14418,7 @@ TIMER_FUNC(status_change_timer){
if (!caster || caster->bl.m != bl->m) //End the SC if caster isn't in same map
break;
sc_timer_next(1000 + tick);
clif_crimson_marker(caster, bl, false);
clif_crimson_marker( *caster, *bl, false );
return 0;
}
break;

View File

@ -1858,9 +1858,6 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
}
}
if (src->type == BL_NPC) // NPC-objects can override cast distance
range = AREA_SIZE; // Maximum visible distance before NPC goes out of sight
else
range = skill_get_range2(src, skill_id, skill_lv, true); // Skill cast distance from database
// New action request received, delete previous action request if not executed yet
@ -1877,7 +1874,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
// Check range when not using skill on yourself or is a combo-skill during attack
// (these are supposed to always have the same range as your attack)
if( src->id != target_id && (!combo || ud->attacktimer == INVALID_TIMER) ) {
if( src->type != BL_NPC && src->id != target_id && (!combo || ud->attacktimer == INVALID_TIMER) ) {
if( skill_get_state(ud->skill_id) == ST_MOVE_ENABLE ) {
if( !unit_can_reach_bl(src, target, range + 1, 1, NULL, NULL) )
return 0; // Walk-path check failed.

View File

@ -5,8 +5,8 @@ out=npc/scripts_custom.conf
printf "\n" >> $out
echo "// Custom Scripts" >> $out
find npc/custom \( -name "*.txt" \) | xargs -I % echo "npc: %" >> $out
find npc/custom \( -name "*.txt" \) | sort | xargs -I % echo "npc: %" >> $out
echo "// Test Scripts" >> $out
find npc/test \( -name "*.txt" \) | xargs -I % echo "npc: %" >> $out
find npc/test \( -name "*.txt" \) | sort | xargs -I % echo "npc: %" >> $out

View File

@ -1,20 +1,20 @@
#!/bin/sh
#source var/function
. ./function.sh
echo "My pkg path is $PKG_PATH"
echo "My pkg path is ${PKG_PATH}"
check_inst_right
read -p "WARNING: This script is experimental. Press Ctrl+C to cancel or Enter to continue." readEnterKey
case $1 in
'bin')
echo "Starting binary cleanup"
rm -rf $PKG_PATH/bin/*
rm -rf "${PKG_PATH:?}"/bin/*
echo "Binary files have been deleted"
;;
'all')
echo "Starting uninstall"
rm -rf $PKG_PATH
rm -rf /usr/bin/$PKG
rm -rf "${PKG_PATH:?}"
rm -rf "/usr/bin/${PKG:?}"
echo "Uninstallation has succeed"
;;
*)