Merge branch 'master' into hotfix/issue4984

This commit is contained in:
Aleos 2022-12-14 14:41:56 -05:00 committed by GitHub
commit 1c1bb9892c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 3462 additions and 3279 deletions

View File

@ -158,3 +158,14 @@ macro_detection_retry: 3
// Amount of time in milliseconds before the macro detection will fail and the user will be banned. // Amount of time in milliseconds before the macro detection will fail and the user will be banned.
// Official: 60000 // Official: 60000
macro_detection_timeout: 60000 macro_detection_timeout: 60000
// Macro Detector punishment type
// 0 - Ban
// 1 - Jail
// Official: 0
macro_detection_punishment: 0
// Macro Detector punishment duration
// Amount of time in minutes that the punishment type is active for. Use 0 for infinite.
// Official: 0
macro_detection_punishment_time: 0

View File

@ -297,3 +297,8 @@ achievement_mob_share: no
// Should slaves teleport back to their master if they get too far during chase? (Note 1) // Should slaves teleport back to their master if they get too far during chase? (Note 1)
// Default (Official): no // Default (Official): no
slave_stick_with_master: no slave_stick_with_master: no
// Absolute minimum respawn time in milliseconds of a monster.
// Also used in delaying the spawning of guardians when a guild is not loaded.
// Default (Official): 1000
mob_respawn_time: 1000

View File

@ -1987,7 +1987,6 @@ Body:
Flags: Flags:
NoRemoveOnDead: true NoRemoveOnDead: true
NoClearbuff: true NoClearbuff: true
NoDispell: true
NoBanishingBuster: true NoBanishingBuster: true
NoClearance: true NoClearance: true
- Status: Incmhprate - Status: Incmhprate

View File

@ -27608,8 +27608,8 @@ Body:
DamageFlags: DamageFlags:
Splash: true Splash: true
Range: 9 Range: 9
Hit: Single Hit: Multi_Hit
HitCount: -3 HitCount: 3
Element: Wind Element: Wind
SplashArea: SplashArea:
- Level: 1 - Level: 1

View File

@ -2101,7 +2101,6 @@ Body:
Flags: Flags:
NoRemoveOnDead: true NoRemoveOnDead: true
NoClearbuff: true NoClearbuff: true
NoDispell: true
NoBanishingBuster: true NoBanishingBuster: true
NoClearance: true NoClearance: true
- Status: Incmhprate - Status: Incmhprate

View File

@ -159,7 +159,8 @@ executed, it is affected by spawn rates in 'battle_athena.conf'.
Delay1 and delay2 control monster respawn delays - the first one is the fixed Delay1 and delay2 control monster respawn delays - the first one is the fixed
base respawn time, and the second is random variance on top of the base time. base respawn time, and the second is random variance on top of the base time.
Both values are given in milliseconds (1000 = 1 second). Both values are given in milliseconds (1000 = 1 second).
Note that the server also enforces a minimum respawn delay of 5 seconds. Note that the server also enforces a minimum respawn delay of 1 second (See
/conf/battle/monster.conf::mob_respawn_time).
Event is a script event to be executed when the mob is killed. The event must Event is a script event to be executed when the mob is killed. The event must
be in the form "NPCName::OnEventName" to execute, and the event name label be in the form "NPCName::OnEventName" to execute, and the event name label
@ -6579,6 +6580,28 @@ Examples:
--------------------------------------- ---------------------------------------
macro_detector({<account ID>});
macro_detector({"<character name>"});
This command will display the captcha UI challenge onto the invoking character or the given <account ID>/<character name>.
Example:
// Use 'getareaunits' to gather an area of players to test.
// Build an int array of the account IDs.
.@num = getareaunits(BL_PC, "prontera", 150, 150, 160, 160, .@array[0]);
mes "The number of Players in Prontera in between 150x150 and 160x160 is " + .@num + " .";
mes "Players to challenge:";
freeloop(1); // If the list is too big
for(.@i = 0; .@i < getarraysize(.@array); .@i++) {
mes (.@i + 1) + " " + convertpcinfo(.@array[.@i], CPC_NAME);
macro_detector .@array[.@i];
}
freeloop(0);
end;
---------------------------------------
================================== ==================================
|5.- Mob / NPC -related commands.| |5.- Mob / NPC -related commands.|
================================== ==================================

View File

@ -14,7 +14,7 @@
// nyd_dun01 - Yggdrasil Root Dungeon // nyd_dun01 - Yggdrasil Root Dungeon
//================================================== //==================================================
nyd_dun01,0,0 monster Draco 2013,40 nyd_dun01,0,0 monster Draco 2013,40
nyd_dun01,0,0 monster Draco's Egg 2014,10,0,0,0 nyd_dun01,0,0 monster Draco's Egg 2014,10
nyd_dun01,0,0 monster Aqua Elemental 2016,20 nyd_dun01,0,0 monster Aqua Elemental 2016,20
nyd_dun01,0,0 monster Dark Pinguicula 2015,10 nyd_dun01,0,0 monster Dark Pinguicula 2015,10
nyd_dun01,0,0 monster Rata 2017,2,900000 nyd_dun01,0,0 monster Rata 2017,2,900000

View File

@ -84,7 +84,7 @@ prt_maze03,50,150,70,70 monster Vagabond Wolf 1092,1,1920000,150000
prt_maze03,170,170,70,70 monster Mantis 1139,30,60000,30000 prt_maze03,170,170,70,70 monster Mantis 1139,30,60000,30000
prt_maze03,170,170,70,70 monster Eclipse 1093,1,1920000,150000 prt_maze03,170,170,70,70 monster Eclipse 1093,1,1920000,150000
prt_maze03,23,23,70,70 monster Mastering 1090,1,1920000,150000 prt_maze03,23,23,70,70 monster Mastering 1090,1,1920000,150000
prt_maze03,100,100,80,80 monster Baphomet Jr. 1101,25,0,0,0 prt_maze03,100,100,80,80 monster Baphomet Jr. 1101,25
prt_maze03,0,0,0,0 boss_monster Baphomet 1039,1,7200000,600000,1 prt_maze03,0,0,0,0 boss_monster Baphomet 1039,1,7200000,600000,1
prt_maze03,61,98,10,10 monster Shining Plant 1083,1,1800000,900000 prt_maze03,61,98,10,10 monster Shining Plant 1083,1,1800000,900000
prt_maze03,61,98,10,10 monster Blue Plant 1079,1,1800000,900000 prt_maze03,61,98,10,10 monster Blue Plant 1079,1,1800000,900000

View File

@ -184,11 +184,11 @@ gl_step,0,0 monster Mimic 1191,6,5000
//================================================== //==================================================
// gl_cas02_ - Nightmare Mode 2f // gl_cas02_ - Nightmare Mode 2f
//================================================== //==================================================
gl_cas02_,0,0 monster Evil Druid (Nightmare) 2480,4,0,0,0 gl_cas02_,0,0 monster Evil Druid (Nightmare) 2480,4,5000
gl_cas02_,0,0 monster Chimera (Nightmare) 2485,1,0,0,0 gl_cas02_,0,0 monster Chimera (Nightmare) 2485,1,5000
gl_cas02_,0,0 monster Mimic (Nightmare) 2479,19,0,0,0 gl_cas02_,0,0 monster Mimic (Nightmare) 2479,19,5000
gl_cas02_,0,0 monster Rideword (Nightmare) 2478,10,0,0,0 gl_cas02_,0,0 monster Rideword (Nightmare) 2478,10,5000
gl_cas02_,0,0 monster Wanderer (Nightmare) 2477,60,0,0,0 gl_cas02_,0,0 monster Wanderer (Nightmare) 2477,60,5000
gl_cas02_,0,0 monster Mysteltainn 1203,1,7200000,3600000 gl_cas02_,0,0 monster Mysteltainn 1203,1,7200000,3600000
gl_cas02_,0,0 monster Alice 1275,1,5000 gl_cas02_,0,0 monster Alice 1275,1,5000
gl_cas02_,102,180 monster Whisper 1185,1,1800000,900000 gl_cas02_,102,180 monster Whisper 1185,1,1800000,900000
@ -197,8 +197,8 @@ gl_cas02_,0,0 monster Baphomet (Nightmare) 2483,1,7200000,0,0
//================================================== //==================================================
// gl_chyard_ - Nightmare Mode Churchyard // gl_chyard_ - Nightmare Mode Churchyard
//================================================== //==================================================
gl_chyard_,0,0 monster Wraith Dead (Nightmare) 2481,91,0,0,0 gl_chyard_,0,0 monster Wraith Dead (Nightmare) 2481,91,5000
gl_chyard_,0,0 monster Wraith Dead 1291,31,0,0,0 gl_chyard_,0,0 monster Wraith Dead 1291,31,5000
gl_chyard_,0,0 monster Evil Druid (Nightmare) 2480,22,60000,0,0 gl_chyard_,0,0 monster Evil Druid (Nightmare) 2480,22,60000,0,0
gl_chyard_,0,0 monster Mimic (Nightmare) 2479,34,60000,0,0 gl_chyard_,0,0 monster Mimic (Nightmare) 2479,34,60000,0,0
gl_chyard_,0,0,0,0 boss_monster Dark Lord 1272,1,3600000,600000,1 gl_chyard_,0,0,0,0 boss_monster Dark Lord 1272,1,3600000,600000,1

View File

@ -10,28 +10,28 @@
//============================================================ //============================================================
// ver_eju // ver_eju
ver_eju,0,0,0,0 monster Recon Robot 3154,50,0,0,0 ver_eju,0,0,0,0 monster Recon Robot 3154,50,5000
ver_eju,0,0,0,0 monster Excavator Robot 3153,10,0,0,0 ver_eju,0,0,0,0 monster Excavator Robot 3153,10,5000
// ver_tunn // ver_tunn
ver_tunn,0,0,0,0 monster Recon Robot 3154,5,0,0,0 ver_tunn,0,0,0,0 monster Recon Robot 3154,5,30000
// verus01 // verus01
verus01,0,0,0,0 monster Green Cenere 3247,50,0,0,0 verus01,0,0,0,0 monster Green Cenere 3247,50,5000
verus01,0,0,0,0 monster Explorer Robot Turbo 3249,25,0,0,0 verus01,0,0,0,0 monster Explorer Robot Turbo 3249,25,5000
verus01,0,0,0,0 monster Repair Robot Turbo 3248,25,0,0,0 verus01,0,0,0,0 monster Repair Robot Turbo 3248,25,5000
// verus02 // verus02
verus02,0,0,0,0 monster Repair Robot Turbo 3248,50,0,0,0 verus02,0,0,0,0 monster Repair Robot Turbo 3248,50,5000
verus02,0,0,0,0 monster Explorer Robot Turbo 3249,50,0,0,0 verus02,0,0,0,0 monster Explorer Robot Turbo 3249,50,5000
// verus03 // verus03
verus03,0,0,0,0 monster Illegal Promotion 3159,40,0,0,0 verus03,0,0,0,0 monster Illegal Promotion 3159,40,5000
verus03,0,0,0,0 monster Explorer Robot 3156,50,0,0,0 verus03,0,0,0,0 monster Explorer Robot 3156,50,5000
verus03,0,0,0,0 monster Repair Robot 3155,50,0,0,0 verus03,0,0,0,0 monster Repair Robot 3155,50,5000
verus03,0,0,0,0 monster Ruin Grace Believer 3158,10,0,0,0 verus03,0,0,0,0 monster Ruin Grace Believer 3158,10,5000
// un_bunker // un_bunker
un_bunker,0,0,0,0 monster Thief Bug 1051,6,0,0,0 un_bunker,0,0,0,0 monster Thief Bug 1051,6,5000
un_bunker,0,0,0,0 monster Smelly Ghoul 3255,68,0,0,0 un_bunker,0,0,0,0 monster Smelly Ghoul 3255,68,5000
un_bunker,0,0,0,0 monster Smelly Zombie 3256,80,0,0,0 un_bunker,0,0,0,0 monster Smelly Zombie 3256,80,5000
un_bunker,0,0,0,0 monster Machine Component 3250,28,0,0,0 un_bunker,0,0,0,0 monster Machine Component 3250,28,5000
un_bunker,0,0,0,0 monster DR815 3252,14,0,0,0 un_bunker,0,0,0,0 monster DR815 3252,14,5000
un_bunker,0,0,0,0 monster GC109 3251,10,0,0,0 un_bunker,0,0,0,0 monster GC109 3251,10,5000
un_bunker,0,0,0,0 monster Black Mushroom 1084,1,0,0,0 un_bunker,0,0,0,0 monster Black Mushroom 1084,1,5000
un_bunker,0,0,0,0 monster Chonchon 1011,2,0,0,0 un_bunker,0,0,0,0 monster Chonchon 1011,2,5000

View File

@ -6,19 +6,19 @@ The files in this directory are basic SQL table building scripts. The contained
### New Install ### New Install
--- ---
For a new install, the following needs to be imported into the 'ragnarok' schema: For a new install, the following needs to be imported into the main schema:
Note: The schema name is defined in `conf/inter_athena.conf::map_server_db`. Note: The schema name is defined in `conf/inter_athena.conf::map_server_db`.
* main.sql - Contains tables for normal server usage. * main.sql - Contains tables for normal server usage.
* web.sql - Contains tables for the web service * web.sql - Contains tables for the web service
* roulette_default_data.sql - Contains data for the client's roulette game. * roulette_default_data.sql - Contains data for the client's roulette game.
For a new install, the following needs to be imported into the 'log' schema: For a new install, the following can be imported into the main schema but is highly suggested to be imported into a separate schema for logs:
Note: The schema name is defined in `conf/inter_athena.conf::log_db_db`. Note: The schema name is defined in `conf/inter_athena.conf::log_db_db`.
* logs.sql - Contains tables for logging of server events. * logs.sql - Contains tables for logging of server events.
If your server is setup to read SQL database data, import the following: If your server is setup to read SQL database data, import the following into the main schema:
Note: If `conf/inter_athena.conf::use_sql_db` is set to yes continue with these imports else these can be skipped. Not all files have to be imported, only the ones that apply to the same mode as the server being ran. Note: If `conf/inter_athena.conf::use_sql_db` is set to yes continue with these imports else these can be skipped. Not all files have to be imported, only the ones that apply to the same mode as the server being ran.
* item_cash_db.sql - Used for client's cash shop. * item_cash_db.sql - Used for client's cash shop.
@ -44,8 +44,8 @@ Note: If `conf/inter_athena.conf::use_sql_db` is set to yes continue with these
### Updates ### Updates
--- ---
Over the course of time new features and optimizations will take place. This may require SQL changes to happen. In the `upgrades` folder will be upgrade files with an attached date. Over the course of time new features and optimizations will take place. This may require SQL changes to happen. In the `upgrades` folder will be SQL files with an attached date.
These imports only have to executed if an update has occurred after the initial installation. Many times a SQL error will be displayed on the server console stating the format differs from what is required. These only have to executed one time if an update has occurred after the initial installation. It's possible to see when an update may be required when a SQL error will be displayed on the server console stating the format differs from what is required.
### Compatibility ### Compatibility
--- ---
@ -76,4 +76,4 @@ To run these queries the user requires the [FILE](https://dev.mysql.com/doc/refm
### Notes ### Notes
--- ---
The web-server must be able to read the `login` and `guild` tables from the `login-server` and `char-server`, respectively. The `web-server` must be able to read the `login` and `guild` tables from the `login-server` and `char-server`, respectively.

View File

@ -5218,8 +5218,7 @@ ACMD_FUNC(servertime)
ACMD_FUNC(jail) ACMD_FUNC(jail)
{ {
struct map_session_data *pl_sd; struct map_session_data *pl_sd;
int x, y;
unsigned short m_index;
nullpo_retr(-1, sd); nullpo_retr(-1, sd);
memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
@ -5239,26 +5238,12 @@ ACMD_FUNC(jail)
return -1; return -1;
} }
if (pl_sd->sc.data[SC_JAILED]) { if (pl_sd->sc.getSCE(SC_JAILED)) {
clif_displaymessage(fd, msg_txt(sd,118)); // Player warped in jails. clif_displaymessage(fd, msg_txt(sd,118)); // Player warped in jails.
return -1; return -1;
} }
switch(rnd() % 2) { //Jail Locations pc_jail(*pl_sd);
case 0:
m_index = mapindex_name2id(MAP_JAIL);
x = 24;
y = 75;
break;
default:
m_index = mapindex_name2id(MAP_JAIL);
x = 49;
y = 75;
break;
}
//Duration of INT_MAX to specify infinity.
sc_start4(NULL,&pl_sd->bl,SC_JAILED,100,INT_MAX,m_index,x,y,1000);
clif_displaymessage(pl_sd->fd, msg_txt(sd,117)); // GM has send you in jails. clif_displaymessage(pl_sd->fd, msg_txt(sd,117)); // GM has send you in jails.
clif_displaymessage(fd, msg_txt(sd,118)); // Player warped in jails. clif_displaymessage(fd, msg_txt(sd,118)); // Player warped in jails.
return 0; return 0;
@ -5290,13 +5275,13 @@ ACMD_FUNC(unjail)
return -1; return -1;
} }
if (!pl_sd->sc.data[SC_JAILED]) { if (!pl_sd->sc.getSCE(SC_JAILED)) {
clif_displaymessage(fd, msg_txt(sd,119)); // This player is not in jails. clif_displaymessage(fd, msg_txt(sd,119)); // This player is not in jails.
return -1; return -1;
} }
//Reset jail time to 1 sec. //Reset jail time to 1 sec.
sc_start(NULL,&pl_sd->bl,SC_JAILED,100,1,1000); pc_jail(*pl_sd, 0);
clif_displaymessage(pl_sd->fd, msg_txt(sd,120)); // A GM has discharged you from jail. clif_displaymessage(pl_sd->fd, msg_txt(sd,120)); // A GM has discharged you from jail.
clif_displaymessage(fd, msg_txt(sd,121)); // Player unjailed. clif_displaymessage(fd, msg_txt(sd,121)); // Player unjailed.
return 0; return 0;
@ -5305,8 +5290,8 @@ ACMD_FUNC(unjail)
ACMD_FUNC(jailfor) { ACMD_FUNC(jailfor) {
struct map_session_data *pl_sd = NULL; struct map_session_data *pl_sd = NULL;
char * modif_p; char * modif_p;
int jailtime = 0,x,y; int jailtime = 0;
short m_index = 0;
nullpo_retr(-1, sd); nullpo_retr(-1, sd);
memset(atcmd_output, '\0', sizeof(atcmd_output)); memset(atcmd_output, '\0', sizeof(atcmd_output));
@ -5338,8 +5323,8 @@ ACMD_FUNC(jailfor) {
} }
// Added by Coltaro // Added by Coltaro
if(pl_sd->sc.data[SC_JAILED] && pl_sd->sc.data[SC_JAILED]->val1 != INT_MAX) { // Update the player's jail time if(pl_sd->sc.getSCE(SC_JAILED) && pl_sd->sc.getSCE(SC_JAILED)->val1 != INT_MAX) { // Update the player's jail time
jailtime += pl_sd->sc.data[SC_JAILED]->val1; jailtime += pl_sd->sc.getSCE(SC_JAILED)->val1;
if (jailtime <= 0) { if (jailtime <= 0) {
jailtime = 0; jailtime = 0;
clif_displaymessage(pl_sd->fd, msg_txt(sd,120)); // GM has discharge you. clif_displaymessage(pl_sd->fd, msg_txt(sd,120)); // GM has discharge you.
@ -5363,19 +5348,8 @@ ACMD_FUNC(jailfor) {
return -1; return -1;
} }
// Jail locations, add more as you wish. pc_jail(*pl_sd, jailtime);
switch(rnd()%2) {
case 1: // Jail #1
m_index = mapindex_name2id(MAP_JAIL);
x = 49; y = 75;
break;
default: // Default Jail
m_index = mapindex_name2id(MAP_JAIL);
x = 24; y = 75;
break;
}
sc_start4(NULL,&pl_sd->bl,SC_JAILED,100,jailtime,m_index,x,y,jailtime?60000:1000); //jailtime = 0: Time was reset to 0. Wait 1 second to warp player out (since it's done in status_change_timer).
return 0; return 0;
} }
@ -5387,26 +5361,26 @@ ACMD_FUNC(jailtime){
nullpo_retr(-1, sd); nullpo_retr(-1, sd);
if (!sd->sc.data[SC_JAILED]) { if (!sd->sc.getSCE(SC_JAILED)) {
clif_displaymessage(fd, msg_txt(sd,1139)); // You are not in jail. clif_displaymessage(fd, msg_txt(sd,1139)); // You are not in jail.
return -1; return -1;
} }
if (sd->sc.data[SC_JAILED]->val1 == INT_MAX) { if (sd->sc.getSCE(SC_JAILED)->val1 == INT_MAX) {
clif_displaymessage(fd, msg_txt(sd,1140)); // You have been jailed indefinitely. clif_displaymessage(fd, msg_txt(sd,1140)); // You have been jailed indefinitely.
return 0; return 0;
} }
if (sd->sc.data[SC_JAILED]->val1 <= 0) { // Was not jailed with @jailfor (maybe @jail? or warped there? or got recalled?) if (sd->sc.getSCE(SC_JAILED)->val1 <= 0) { // Was not jailed with @jailfor (maybe @jail? or warped there? or got recalled?)
clif_displaymessage(fd, msg_txt(sd,1141)); // You have been jailed for an unknown amount of time. clif_displaymessage(fd, msg_txt(sd,1141)); // You have been jailed for an unknown amount of time.
return -1; return -1;
} }
// Get remaining jail time // Get remaining jail time
split_time(sd->sc.data[SC_JAILED]->val1*60,&year,&month,&day,&hour,&minute,&second); split_time(sd->sc.getSCE(SC_JAILED)->val1*60,&year,&month,&day,&hour,&minute,&second);
sprintf(atcmd_output,msg_txt(sd,402),msg_txt(sd,1142),year,month,day,hour,minute); // You will remain in jail for %d years, %d months, %d days, %d hours and %d minutes sprintf(atcmd_output,msg_txt(sd,402),msg_txt(sd,1142),year,month,day,hour,minute); // You will remain in jail for %d years, %d months, %d days, %d hours and %d minutes
clif_displaymessage(fd, atcmd_output); clif_displaymessage(fd, atcmd_output);
timestamp2string(timestr,20,now+sd->sc.data[SC_JAILED]->val1*60,"%Y-%m-%d %H:%M"); timestamp2string(timestr,20,now+sd->sc.getSCE(SC_JAILED)->val1*60,"%Y-%m-%d %H:%M");
sprintf(atcmd_output,"Release date is: %s",timestr); sprintf(atcmd_output,"Release date is: %s",timestr);
clif_displaymessage(fd, atcmd_output); clif_displaymessage(fd, atcmd_output);
@ -5451,7 +5425,7 @@ ACMD_FUNC(disguise)
return -1; return -1;
} }
if (sd->sc.data[SC_MONSTER_TRANSFORM] || sd->sc.data[SC_ACTIVE_MONSTER_TRANSFORM]) { if (sd->sc.getSCE(SC_MONSTER_TRANSFORM) || sd->sc.getSCE(SC_ACTIVE_MONSTER_TRANSFORM)) {
clif_displaymessage(fd, msg_txt(sd,730)); // Character cannot be disguised while in monster transform. clif_displaymessage(fd, msg_txt(sd,730)); // Character cannot be disguised while in monster transform.
return -1; return -1;
} }
@ -7438,7 +7412,7 @@ ACMD_FUNC(unmute)
return -1; return -1;
} }
if(!pl_sd->sc.data[SC_NOCHAT]) { if(!pl_sd->sc.getSCE(SC_NOCHAT)) {
clif_displaymessage(sd->fd,msg_txt(sd,1235)); // Player is not muted. clif_displaymessage(sd->fd,msg_txt(sd,1235)); // Player is not muted.
return -1; return -1;
} }
@ -9733,7 +9707,7 @@ ACMD_FUNC(charcommands) {
/* for new mounts */ /* for new mounts */
ACMD_FUNC(mount2) { ACMD_FUNC(mount2) {
clif_displaymessage(sd->fd,msg_txt(sd,1362)); // NOTICE: If you crash with mount your LUA is outdated. clif_displaymessage(sd->fd,msg_txt(sd,1362)); // NOTICE: If you crash with mount your LUA is outdated.
if (!sd->sc.data[SC_ALL_RIDING]) { if (!sd->sc.getSCE(SC_ALL_RIDING)) {
clif_displaymessage(sd->fd,msg_txt(sd,1363)); // You have mounted. clif_displaymessage(sd->fd,msg_txt(sd,1363)); // You have mounted.
sc_start(NULL, &sd->bl, SC_ALL_RIDING, 10000, 1, INFINITE_TICK); sc_start(NULL, &sd->bl, SC_ALL_RIDING, 10000, 1, INFINITE_TICK);
} else { } else {
@ -10332,7 +10306,7 @@ ACMD_FUNC(changedress){
}; };
for( sc_type type : name2id ) { for( sc_type type : name2id ) {
if( sd->sc.data[type] ) { if( sd->sc.getSCE(type) ) {
status_change_end( &sd->bl, type ); status_change_end( &sd->bl, type );
// You should only be able to have one - so we cancel here // You should only be able to have one - so we cancel here
break; break;
@ -10363,7 +10337,7 @@ ACMD_FUNC(costume) {
if( !message || !*message ) { if( !message || !*message ) {
for( k = 0; k < len; k++ ) { for( k = 0; k < len; k++ ) {
if( sd->sc.data[name2id[k]] ) { if( sd->sc.getSCE(name2id[k]) ) {
sprintf(atcmd_output, msg_txt(sd, 727), names[k]); // '%s' Costume removed. sprintf(atcmd_output, msg_txt(sd, 727), names[k]); // '%s' Costume removed.
clif_displaymessage(sd->fd, atcmd_output); clif_displaymessage(sd->fd, atcmd_output);
status_change_end(&sd->bl, (sc_type)name2id[k]); status_change_end(&sd->bl, (sc_type)name2id[k]);
@ -10380,7 +10354,7 @@ ACMD_FUNC(costume) {
} }
for( k = 0; k < len; k++ ) { for( k = 0; k < len; k++ ) {
if( sd->sc.data[name2id[k]] ) { if( sd->sc.getSCE(name2id[k]) ) {
sprintf(atcmd_output, msg_txt(sd, 724), names[k]); // You're already wearing a(n) '%s' costume, type '@costume' to remove it. sprintf(atcmd_output, msg_txt(sd, 724), names[k]); // You're already wearing a(n) '%s' costume, type '@costume' to remove it.
clif_displaymessage(sd->fd, atcmd_output); clif_displaymessage(sd->fd, atcmd_output);
return -1; return -1;
@ -11309,7 +11283,7 @@ bool is_atcommand(const int fd, struct map_session_data* sd, const char* message
return false; return false;
//Block NOCHAT but do not display it as a normal message //Block NOCHAT but do not display it as a normal message
if ( sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCOMMAND ) if ( sd->sc.getSCE(SC_NOCHAT) && sd->sc.getSCE(SC_NOCHAT)->val1&MANNER_NOCOMMAND )
return true; return true;
// skip 10/11-langtype's codepage indicator, if detected // skip 10/11-langtype's codepage indicator, if detected

File diff suppressed because it is too large Load Diff

View File

@ -714,12 +714,16 @@ struct Battle_Config
int break_mob_equip; int break_mob_equip;
int macro_detection_retry; int macro_detection_retry;
int macro_detection_timeout; int macro_detection_timeout;
int macro_detection_punishment;
int macro_detection_punishment_time;
int feature_dynamicnpc_timeout; int feature_dynamicnpc_timeout;
int feature_dynamicnpc_rangex; int feature_dynamicnpc_rangex;
int feature_dynamicnpc_rangey; int feature_dynamicnpc_rangey;
int feature_dynamicnpc_direction; int feature_dynamicnpc_direction;
int mob_respawn_time;
#include "../custom/battle_config_struct.inc" #include "../custom/battle_config_struct.inc"
}; };

View File

@ -848,18 +848,18 @@ static bool bg_queue_check_status(struct map_session_data* sd, const char *name)
nullpo_retr(false, sd); nullpo_retr(false, sd);
if (sd->sc.count) { if (sd->sc.count) {
if (sd->sc.data[SC_ENTRY_QUEUE_APPLY_DELAY]) { // Exclude any player who's recently left a battleground queue if (sd->sc.getSCE(SC_ENTRY_QUEUE_APPLY_DELAY)) { // Exclude any player who's recently left a battleground queue
char buf[CHAT_SIZE_MAX]; char buf[CHAT_SIZE_MAX];
sprintf(buf, msg_txt(sd, 339), static_cast<int32>((get_timer(sd->sc.data[SC_ENTRY_QUEUE_APPLY_DELAY]->timer)->tick - gettick()) / 1000)); // You can't apply to a battleground queue for %d seconds due to recently leaving one. sprintf(buf, msg_txt(sd, 339), static_cast<int32>((get_timer(sd->sc.getSCE(SC_ENTRY_QUEUE_APPLY_DELAY)->timer)->tick - gettick()) / 1000)); // You can't apply to a battleground queue for %d seconds due to recently leaving one.
clif_bg_queue_apply_result(BG_APPLY_NONE, name, sd); clif_bg_queue_apply_result(BG_APPLY_NONE, name, sd);
clif_messagecolor(&sd->bl, color_table[COLOR_LIGHT_GREEN], buf, false, SELF); clif_messagecolor(&sd->bl, color_table[COLOR_LIGHT_GREEN], buf, false, SELF);
return false; return false;
} }
if (sd->sc.data[SC_ENTRY_QUEUE_NOTIFY_ADMISSION_TIME_OUT]) { // Exclude any player who's recently deserted a battleground if (sd->sc.getSCE(SC_ENTRY_QUEUE_NOTIFY_ADMISSION_TIME_OUT)) { // Exclude any player who's recently deserted a battleground
char buf[CHAT_SIZE_MAX]; char buf[CHAT_SIZE_MAX];
int32 status_tick = static_cast<int32>(DIFF_TICK(get_timer(sd->sc.data[SC_ENTRY_QUEUE_NOTIFY_ADMISSION_TIME_OUT]->timer)->tick, gettick()) / 1000); int32 status_tick = static_cast<int32>(DIFF_TICK(get_timer(sd->sc.getSCE(SC_ENTRY_QUEUE_NOTIFY_ADMISSION_TIME_OUT)->timer)->tick, gettick()) / 1000);
sprintf(buf, msg_txt(sd, 338), status_tick / 60, status_tick % 60); // You can't apply to a battleground queue due to recently deserting a battleground. Time remaining: %d minutes and %d seconds. sprintf(buf, msg_txt(sd, 338), status_tick / 60, status_tick % 60); // You can't apply to a battleground queue due to recently deserting a battleground. Time remaining: %d minutes and %d seconds.
clif_bg_queue_apply_result(BG_APPLY_NONE, name, sd); clif_bg_queue_apply_result(BG_APPLY_NONE, name, sd);

View File

@ -73,7 +73,7 @@ int8 buyingstore_setup(struct map_session_data* sd, unsigned char slots){
return 1; return 1;
} }
if( sd->sc.data[SC_NOCHAT] && (sd->sc.data[SC_NOCHAT]->val1&MANNER_NOROOM) ) if( sd->sc.getSCE(SC_NOCHAT) && (sd->sc.getSCE(SC_NOCHAT)->val1&MANNER_NOROOM) )
{// custom: mute limitation {// custom: mute limitation
return 2; return 2;
} }
@ -140,7 +140,7 @@ int8 buyingstore_create( struct map_session_data* sd, int zenylimit, unsigned ch
return 6; return 6;
} }
if( sd->sc.data[SC_NOCHAT] && (sd->sc.data[SC_NOCHAT]->val1&MANNER_NOROOM) ) if( sd->sc.getSCE(SC_NOCHAT) && (sd->sc.getSCE(SC_NOCHAT)->val1&MANNER_NOROOM) )
{// custom: mute limitation {// custom: mute limitation
return 2; return 2;
} }

View File

@ -171,6 +171,7 @@ bool chrif_auth_delete(uint32 account_id, uint32 char_id, enum sd_state state) {
if (node->sd->regs.arrays) if (node->sd->regs.arrays)
node->sd->regs.arrays->destroy(node->sd->regs.arrays, script_free_array_db); node->sd->regs.arrays->destroy(node->sd->regs.arrays, script_free_array_db);
node->sd->~map_session_data();
aFree(node->sd); aFree(node->sd);
} }
@ -1325,10 +1326,11 @@ int chrif_save_scdata(struct map_session_data *sd) { //parses the sc_data of the
WFIFOL(char_fd,8) = sd->status.char_id; WFIFOL(char_fd,8) = sd->status.char_id;
for (i = 0; i < SC_MAX; i++) { for (i = 0; i < SC_MAX; i++) {
if (!sc->data[i]) auto sce = sc->getSCE(static_cast<sc_type>(i));
if (!sce)
continue; continue;
if (sc->data[i]->timer != INVALID_TIMER) { if (sce->timer != INVALID_TIMER) {
timer = get_timer(sc->data[i]->timer); timer = get_timer(sce->timer);
if (timer == NULL || timer->func != status_change_timer) if (timer == NULL || timer->func != status_change_timer)
continue; continue;
if (DIFF_TICK(timer->tick,tick) > 0) if (DIFF_TICK(timer->tick,tick) > 0)
@ -1339,10 +1341,10 @@ int chrif_save_scdata(struct map_session_data *sd) { //parses the sc_data of the
data.tick = INFINITE_TICK; //Infinite duration data.tick = INFINITE_TICK; //Infinite duration
data.tick_total = sc->data[i]->tick_total; data.tick_total = sc->data[i]->tick_total;
data.type = i; data.type = i;
data.val1 = sc->data[i]->val1; data.val1 = sce->val1;
data.val2 = sc->data[i]->val2; data.val2 = sce->val2;
data.val3 = sc->data[i]->val3; data.val3 = sce->val3;
data.val4 = sc->data[i]->val4; data.val4 = sce->val4;
memcpy(WFIFOP(char_fd,14 +count*sizeof(struct status_change_data)), memcpy(WFIFOP(char_fd,14 +count*sizeof(struct status_change_data)),
&data, sizeof(struct status_change_data)); &data, sizeof(struct status_change_data));
count++; count++;

View File

@ -454,7 +454,7 @@ static int clif_send_sub(struct block_list *bl, va_list ap)
/* unless visible, hold it here */ /* unless visible, hold it here */
if (!battle_config.update_enemy_position && clif_ally_only && !sd->special_state.intravision && if (!battle_config.update_enemy_position && clif_ally_only && !sd->special_state.intravision &&
!sd->sc.data[SC_INTRAVISION] && battle_check_target(src_bl,&sd->bl,BCT_ENEMY) > 0) !sd->sc.getSCE(SC_INTRAVISION) && battle_check_target(src_bl,&sd->bl,BCT_ENEMY) > 0)
return 0; return 0;
WFIFOHEAD(fd, len); WFIFOHEAD(fd, len);
@ -1560,13 +1560,13 @@ static void clif_millenniumshield_single(int fd, map_session_data *sd)
{ {
nullpo_retv(sd); nullpo_retv(sd);
if (sd->sc.data[SC_MILLENNIUMSHIELD] == nullptr) if (sd->sc.getSCE(SC_MILLENNIUMSHIELD) == nullptr)
return; return;
WFIFOHEAD(fd, packet_len(0x440)); WFIFOHEAD(fd, packet_len(0x440));
WFIFOW(fd, 0) = 0x440; WFIFOW(fd, 0) = 0x440;
WFIFOL(fd, 2) = sd->bl.id; WFIFOL(fd, 2) = sd->bl.id;
WFIFOW(fd, 6) = sd->sc.data[SC_MILLENNIUMSHIELD]->val2; WFIFOW(fd, 6) = sd->sc.getSCE(SC_MILLENNIUMSHIELD)->val2;
WFIFOW(fd, 8) = 0; WFIFOW(fd, 8) = 0;
WFIFOSET(fd, packet_len(0x440)); WFIFOSET(fd, packet_len(0x440));
} }
@ -1705,8 +1705,8 @@ int clif_spawn( struct block_list *bl, bool walking ){
if (sd->spiritball > 0) if (sd->spiritball > 0)
clif_spiritball(&sd->bl); clif_spiritball(&sd->bl);
if (sd->sc.data[SC_MILLENNIUMSHIELD]) if (sd->sc.getSCE(SC_MILLENNIUMSHIELD))
clif_millenniumshield(&sd->bl, sd->sc.data[SC_MILLENNIUMSHIELD]->val2); clif_millenniumshield(&sd->bl, sd->sc.getSCE(SC_MILLENNIUMSHIELD)->val2);
if (sd->soulball > 0) if (sd->soulball > 0)
clif_soulball(sd); clif_soulball(sd);
if (sd->servantball > 0) if (sd->servantball > 0)
@ -4241,8 +4241,8 @@ void clif_changeoption_target( struct block_list* bl, struct block_list* target
//Whenever we send "changeoption" to the client, the provoke icon is lost //Whenever we send "changeoption" to the client, the provoke icon is lost
//There is probably an option for the provoke icon, but as we don't know it, we have to do this for now //There is probably an option for the provoke icon, but as we don't know it, we have to do this for now
if( sc->data[SC_PROVOKE] ){ if( sc->getSCE(SC_PROVOKE) ){
const struct TimerData *td = get_timer( sc->data[SC_PROVOKE]->timer ); const struct TimerData *td = get_timer( sc->getSCE(SC_PROVOKE)->timer );
clif_status_change( bl, status_db.getIcon(SC_PROVOKE), 1, ( !td ? INFINITE_TICK : DIFF_TICK( td->tick, gettick() ) ), 0, 0, 0 ); clif_status_change( bl, status_db.getIcon(SC_PROVOKE), 1, ( !td ? INFINITE_TICK : DIFF_TICK( td->tick, gettick() ) ), 0, 0, 0 );
} }
@ -4874,7 +4874,7 @@ static void clif_getareachar_pc(struct map_session_data* sd,struct map_session_d
if(dstsd->spiritball > 0) if(dstsd->spiritball > 0)
clif_spiritball( &dstsd->bl, &sd->bl, SELF ); clif_spiritball( &dstsd->bl, &sd->bl, SELF );
if (dstsd->sc.data[SC_MILLENNIUMSHIELD]) if (dstsd->sc.getSCE(SC_MILLENNIUMSHIELD))
clif_millenniumshield_single(sd->fd, dstsd); clif_millenniumshield_single(sd->fd, dstsd);
if (dstsd->spiritcharm_type != CHARM_TYPE_NONE && dstsd->spiritcharm > 0) if (dstsd->spiritcharm_type != CHARM_TYPE_NONE && dstsd->spiritcharm > 0)
clif_spiritcharm_single(sd->fd, dstsd); clif_spiritcharm_single(sd->fd, dstsd);
@ -4899,7 +4899,7 @@ static void clif_getareachar_pc(struct map_session_data* sd,struct map_session_d
if( i < MAX_DEVOTION ) if( i < MAX_DEVOTION )
clif_devotion(&dstsd->bl, sd); clif_devotion(&dstsd->bl, sd);
// display link (dstsd - crusader) to sd // display link (dstsd - crusader) to sd
if( dstsd->sc.data[SC_DEVOTION] && (d_bl = map_id2bl(dstsd->sc.data[SC_DEVOTION]->val1)) != NULL ) if( dstsd->sc.getSCE(SC_DEVOTION) && (d_bl = map_id2bl(dstsd->sc.getSCE(SC_DEVOTION)->val1)) != NULL )
clif_devotion(d_bl, sd); clif_devotion(d_bl, sd);
} }
@ -5086,7 +5086,7 @@ int clif_damage(struct block_list* src, struct block_list* dst, t_tick tick, int
type = clif_calc_delay(type,div,damage+damage2,ddelay); type = clif_calc_delay(type,div,damage+damage2,ddelay);
sc = status_get_sc(dst); sc = status_get_sc(dst);
if(sc && sc->count) { if(sc && sc->count) {
if(sc->data[SC_HALLUCINATION]) { if(sc->getSCE(SC_HALLUCINATION)) {
damage = clif_hallucination_damage(); damage = clif_hallucination_damage();
if(damage2) damage2 = clif_hallucination_damage(); if(damage2) damage2 = clif_hallucination_damage();
} }
@ -5897,7 +5897,7 @@ int clif_skill_damage(struct block_list *src,struct block_list *dst,t_tick tick,
type = clif_calc_delay(type,div,damage,ddelay); type = clif_calc_delay(type,div,damage,ddelay);
if( ( sc = status_get_sc(dst) ) && sc->count ) { if( ( sc = status_get_sc(dst) ) && sc->count ) {
if(sc->data[SC_HALLUCINATION] && damage) if(sc->getSCE(SC_HALLUCINATION) && damage)
damage = clif_hallucination_damage(); damage = clif_hallucination_damage();
} }
@ -5994,7 +5994,7 @@ int clif_skill_damage2(struct block_list *src,struct block_list *dst,t_tick tick
sc = status_get_sc(dst); sc = status_get_sc(dst);
if(sc && sc->count) { if(sc && sc->count) {
if(sc->data[SC_HALLUCINATION] && damage) if(sc->getSCE(SC_HALLUCINATION) && damage)
damage = clif_hallucination_damage(); damage = clif_hallucination_damage();
} }
@ -6444,9 +6444,8 @@ void clif_efst_status_change_sub(struct block_list *tbl, struct block_list *bl,
for (unsigned char i = 0; i < sc_display_count; i++) { for (unsigned char i = 0; i < sc_display_count; i++) {
enum sc_type type = sc_display[i]->type; enum sc_type type = sc_display[i]->type;
struct status_change *sc = status_get_sc(bl); struct status_change *sc = status_get_sc(bl);
const TimerData *td = (sc && sc->data[type] ? get_timer(sc->data[type]->timer) : nullptr); const TimerData *td = (sc && sc->getSCE(type) ? get_timer(sc->getSCE(type)->timer) : nullptr);
t_tick tick_total = 0, tick = 0, cur_tick = gettick(); t_tick tick_total = 0, tick = 0, cur_tick = gettick();
tick_total = DIFF_TICK(sc->data[type]->tick_total, cur_tick); tick_total = DIFF_TICK(sc->data[type]->tick_total, cur_tick);
if (td != nullptr) if (td != nullptr)
@ -6464,8 +6463,8 @@ void clif_efst_status_change_sub(struct block_list *tbl, struct block_list *bl,
} }
break; break;
case SC_HELLS_PLANT: case SC_HELLS_PLANT:
if( sc && sc->data[type] ){ if( sc && sc->getSCE(type) ){
tick = sc->data[type]->val4; tick = sc->getSCE(type)->val4;
} }
break; break;
} }
@ -9352,26 +9351,23 @@ void clif_wedding_effect(struct block_list *bl)
/// Notifies the client of the name of the partner character (ZC_COUPLENAME). /// Notifies the client of the name of the partner character (ZC_COUPLENAME).
/// 01e6 <partner name>.24B /// 01e6 <partner name>.24B
void clif_callpartner(struct map_session_data *sd) void clif_callpartner(struct map_session_data& sd)
{ {
unsigned char buf[26]; PACKET_ZC_COUPLENAME p = { 0 };
nullpo_retv(sd); p.packetType = HEADER_ZC_COUPLENAME;
WBUFW(buf,0) = 0x1e6; if( sd.status.partner_id ) {
struct map_session_data *p_sd = pc_get_partner(&sd);
if( sd->status.partner_id ) { if (p_sd != nullptr && !p_sd->state.autotrade)
const char *p = map_charid2nick(sd->status.partner_id); safestrncpy(p.name, p_sd->status.name, NAME_LENGTH);
struct map_session_data *p_sd = pc_get_partner(sd);
if( p != NULL && p_sd != NULL && !p_sd->state.autotrade )
safestrncpy(WBUFCP(buf,2), p, NAME_LENGTH);
else else
WBUFB(buf,2) = 0; p.name[0] = 0;
} else {// Send zero-length name if no partner, to initialize the client buffer. } else {// Send zero-length name if no partner, to initialize the client buffer.
WBUFB(buf,2) = 0; p.name[0] = 0;
} }
clif_send(buf, packet_len(0x1e6), &sd->bl, AREA); clif_send(&p, sizeof(p), &sd.bl, AREA);
} }
@ -9787,7 +9783,7 @@ void clif_refresh(struct map_session_data *sd)
#endif #endif
if (sd->spiritball) if (sd->spiritball)
clif_spiritball( &sd->bl, &sd->bl, SELF ); clif_spiritball( &sd->bl, &sd->bl, SELF );
if (sd->sc.data[SC_MILLENNIUMSHIELD]) if (sd->sc.getSCE(SC_MILLENNIUMSHIELD))
clif_millenniumshield_single(sd->fd, sd); clif_millenniumshield_single(sd->fd, sd);
if (sd->spiritcharm_type != CHARM_TYPE_NONE && sd->spiritcharm > 0) if (sd->spiritcharm_type != CHARM_TYPE_NONE && sd->spiritcharm > 0)
clif_spiritcharm_single(sd->fd, sd); clif_spiritcharm_single(sd->fd, sd);
@ -10641,6 +10637,8 @@ void clif_parse_WantToConnection(int fd, struct map_session_data* sd)
} }
CREATE(sd, TBL_PC, 1); CREATE(sd, TBL_PC, 1);
// placement new
new(sd) map_session_data();
sd->fd = fd; sd->fd = fd;
#ifdef PACKET_OBFUSCATION #ifdef PACKET_OBFUSCATION
sd->cryptKey = (((((clif_cryptKey[0] * clif_cryptKey[1]) + clif_cryptKey[2]) & 0xFFFFFFFF) * clif_cryptKey[1]) + clif_cryptKey[2]) & 0xFFFFFFFF; sd->cryptKey = (((((clif_cryptKey[0] * clif_cryptKey[1]) + clif_cryptKey[2]) & 0xFFFFFFFF) * clif_cryptKey[1]) + clif_cryptKey[2]) & 0xFFFFFFFF;
@ -10849,7 +10847,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
clif_status_load(&sd->bl, EFST_RIDING, 1); clif_status_load(&sd->bl, EFST_RIDING, 1);
else if (sd->sc.option&OPTION_WUGRIDER) else if (sd->sc.option&OPTION_WUGRIDER)
clif_status_load(&sd->bl, EFST_WUGRIDER, 1); clif_status_load(&sd->bl, EFST_WUGRIDER, 1);
else if (sd->sc.data[SC_ALL_RIDING]) else if (sd->sc.getSCE(SC_ALL_RIDING))
clif_status_load(&sd->bl, EFST_ALL_RIDING, 1); clif_status_load(&sd->bl, EFST_ALL_RIDING, 1);
if(sd->status.manner < 0) if(sd->status.manner < 0)
@ -11031,7 +11029,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
if (sd->sc.opt2) //Client loses these on warp. if (sd->sc.opt2) //Client loses these on warp.
clif_changeoption(&sd->bl); clif_changeoption(&sd->bl);
if ((sd->sc.data[SC_MONSTER_TRANSFORM] || sd->sc.data[SC_ACTIVE_MONSTER_TRANSFORM]) && battle_config.mon_trans_disable_in_gvg && mapdata_flag_gvg2(mapdata)) { if ((sd->sc.getSCE(SC_MONSTER_TRANSFORM) || sd->sc.getSCE(SC_ACTIVE_MONSTER_TRANSFORM)) && battle_config.mon_trans_disable_in_gvg && mapdata_flag_gvg2(mapdata)) {
status_change_end(&sd->bl, SC_MONSTER_TRANSFORM); status_change_end(&sd->bl, SC_MONSTER_TRANSFORM);
status_change_end(&sd->bl, SC_ACTIVE_MONSTER_TRANSFORM); status_change_end(&sd->bl, SC_ACTIVE_MONSTER_TRANSFORM);
clif_displaymessage(sd->fd, msg_txt(sd,731)); // Transforming into monster is not allowed in Guild Wars. clif_displaymessage(sd->fd, msg_txt(sd,731)); // Transforming into monster is not allowed in Guild Wars.
@ -11285,7 +11283,7 @@ void clif_parse_WalkToXY(int fd, struct map_session_data *sd)
} else if (pc_cant_act(sd)) } else if (pc_cant_act(sd))
return; return;
if(sd->sc.data[SC_RUN] || sd->sc.data[SC_WUGDASH]) if(sd->sc.getSCE(SC_RUN) || sd->sc.getSCE(SC_WUGDASH))
return; return;
RFIFOPOS(fd, packet_db[RFIFOW(fd,0)].pos[0], &x, &y, NULL); RFIFOPOS(fd, packet_db[RFIFOW(fd,0)].pos[0], &x, &y, NULL);
@ -11297,8 +11295,8 @@ void clif_parse_WalkToXY(int fd, struct map_session_data *sd)
// Cloaking wall check is actually updated when you click to process next movement // Cloaking wall check is actually updated when you click to process next movement
// not when you move each cell. This is official behaviour. // not when you move each cell. This is official behaviour.
if (sd->sc.data[SC_CLOAKING]) if (sd->sc.getSCE(SC_CLOAKING))
skill_check_cloaking(&sd->bl, sd->sc.data[SC_CLOAKING]); skill_check_cloaking(&sd->bl, sd->sc.getSCE(SC_CLOAKING));
status_change_end(&sd->bl, SC_ROLLINGCUTTER); // If you move, you lose your counters. [malufett] status_change_end(&sd->bl, SC_ROLLINGCUTTER); // If you move, you lose your counters. [malufett]
status_change_end(&sd->bl, SC_CRESCIVEBOLT); status_change_end(&sd->bl, SC_CRESCIVEBOLT);
@ -11341,7 +11339,7 @@ void clif_parse_QuitGame(int fd, struct map_session_data *sd)
{ {
/* Rovert's prevent logout option fixed [Valaris] */ /* Rovert's prevent logout option fixed [Valaris] */
//int type = RFIFOW(fd,packet_db[RFIFOW(fd,0)].pos[0]); //int type = RFIFOW(fd,packet_db[RFIFOW(fd,0)].pos[0]);
if( !sd->sc.data[SC_CLOAKING] && !sd->sc.data[SC_HIDING] && !sd->sc.data[SC_CHASEWALK] && !sd->sc.data[SC_CLOAKINGEXCEED] && !sd->sc.data[SC_SUHIDE] && !sd->sc.data[SC_NEWMOON] && if( !sd->sc.getSCE(SC_CLOAKING) && !sd->sc.getSCE(SC_HIDING) && !sd->sc.getSCE(SC_CHASEWALK) && !sd->sc.getSCE(SC_CLOAKINGEXCEED) && !sd->sc.getSCE(SC_SUHIDE) && !sd->sc.getSCE(SC_NEWMOON) &&
(!battle_config.prevent_logout || sd->canlog_tick == 0 || DIFF_TICK(gettick(), sd->canlog_tick) > battle_config.prevent_logout) ) (!battle_config.prevent_logout || sd->canlog_tick == 0 || DIFF_TICK(gettick(), sd->canlog_tick) > battle_config.prevent_logout) )
{ {
pc_damage_log_clear(sd,0); pc_damage_log_clear(sd,0);
@ -11628,8 +11626,8 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type,
break; break;
if (sd->sc.count && ( if (sd->sc.count && (
sd->sc.data[SC_DANCING] || sd->sc.getSCE(SC_DANCING) ||
(sd->sc.data[SC_GRAVITATION] && sd->sc.data[SC_GRAVITATION]->val3 == BCT_SELF) (sd->sc.getSCE(SC_GRAVITATION) && sd->sc.getSCE(SC_GRAVITATION)->val3 == BCT_SELF)
)) //No sitting during these states either. )) //No sitting during these states either.
break; break;
@ -11714,7 +11712,7 @@ void clif_parse_Restart(int fd, struct map_session_data *sd)
break; break;
case 0x01: case 0x01:
/* Rovert's Prevent logout option - Fixed [Valaris] */ /* Rovert's Prevent logout option - Fixed [Valaris] */
if( !sd->sc.data[SC_CLOAKING] && !sd->sc.data[SC_HIDING] && !sd->sc.data[SC_CHASEWALK] && !sd->sc.data[SC_CLOAKINGEXCEED] && !sd->sc.data[SC_SUHIDE] && !sd->sc.data[SC_NEWMOON] && if( !sd->sc.getSCE(SC_CLOAKING) && !sd->sc.getSCE(SC_HIDING) && !sd->sc.getSCE(SC_CHASEWALK) && !sd->sc.getSCE(SC_CLOAKINGEXCEED) && !sd->sc.getSCE(SC_SUHIDE) && !sd->sc.getSCE(SC_NEWMOON) &&
(!battle_config.prevent_logout || sd->canlog_tick == 0 || DIFF_TICK(gettick(), sd->canlog_tick) > battle_config.prevent_logout) ) (!battle_config.prevent_logout || sd->canlog_tick == 0 || DIFF_TICK(gettick(), sd->canlog_tick) > battle_config.prevent_logout) )
{ //Send to char-server for character selection. { //Send to char-server for character selection.
pc_damage_log_clear(sd,0); pc_damage_log_clear(sd,0);
@ -12238,7 +12236,7 @@ void clif_parse_CreateChatRoom(int fd, struct map_session_data* sd)
char s_password[CHATROOM_PASS_SIZE]; char s_password[CHATROOM_PASS_SIZE];
char s_title[CHATROOM_TITLE_SIZE]; char s_title[CHATROOM_TITLE_SIZE];
if (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOROOM) if (sd->sc.getSCE(SC_NOCHAT) && sd->sc.getSCE(SC_NOCHAT)->val1&MANNER_NOROOM)
return; return;
if(battle_config.basic_skill_check && pc_checkskill(sd,NV_BASIC) < 4 && pc_checkskill(sd, SU_BASIC_SKILL) < 1) { if(battle_config.basic_skill_check && pc_checkskill(sd,NV_BASIC) < 4 && pc_checkskill(sd, SU_BASIC_SKILL) < 1) {
clif_skill_fail(sd,1,USESKILL_FAIL_LEVEL,3); clif_skill_fail(sd,1,USESKILL_FAIL_LEVEL,3);
@ -12478,7 +12476,7 @@ void clif_parse_RemoveOption(int fd,struct map_session_data *sd)
{ {
if( !(sd->sc.option&(OPTION_RIDING|OPTION_FALCON|OPTION_DRAGON|OPTION_MADOGEAR)) if( !(sd->sc.option&(OPTION_RIDING|OPTION_FALCON|OPTION_DRAGON|OPTION_MADOGEAR))
#ifdef NEW_CARTS #ifdef NEW_CARTS
&& sd->sc.data[SC_PUSH_CART] ) && sd->sc.getSCE(SC_PUSH_CART) )
pc_setcart(sd,0); pc_setcart(sd,0);
#else #else
) )
@ -12660,9 +12658,9 @@ static void clif_parse_UseSkillToPos_homun(struct homun_data *hd, struct map_ses
} }
#ifdef RENEWAL #ifdef RENEWAL
if (hd->sc.data[SC_BASILICA_CELL]) if (hd->sc.getSCE(SC_BASILICA_CELL))
#else #else
if (hd->sc.data[SC_BASILICA]) if (hd->sc.getSCE(SC_BASILICA))
#endif #endif
return; return;
lv = hom_checkskill(hd, skill_id); lv = hom_checkskill(hd, skill_id);
@ -12713,9 +12711,9 @@ static void clif_parse_UseSkillToPos_mercenary(s_mercenary_data *md, struct map_
} }
#ifdef RENEWAL #ifdef RENEWAL
if (md->sc.data[SC_BASILICA_CELL]) if (md->sc.getSCE(SC_BASILICA_CELL))
#else #else
if (md->sc.data[SC_BASILICA]) if (md->sc.getSCE(SC_BASILICA))
#endif #endif
return; return;
lv = mercenary_checkskill(md, skill_id); lv = mercenary_checkskill(md, skill_id);
@ -12799,7 +12797,7 @@ void clif_parse_skill_toid( struct map_session_data* sd, uint16 skill_id, uint16
return; return;
#ifndef RENEWAL #ifndef RENEWAL
if( sd->sc.data[SC_BASILICA] && (skill_id != HP_BASILICA || sd->sc.data[SC_BASILICA]->val4 != sd->bl.id) ) if( sd->sc.getSCE(SC_BASILICA) && (skill_id != HP_BASILICA || sd->sc.getSCE(SC_BASILICA)->val4 != sd->bl.id) )
return; // On basilica only caster can use Basilica again to stop it. return; // On basilica only caster can use Basilica again to stop it.
#endif #endif
@ -12915,7 +12913,7 @@ static void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uin
return; return;
#ifndef RENEWAL #ifndef RENEWAL
if( sd->sc.data[SC_BASILICA] && (skill_id != HP_BASILICA || sd->sc.data[SC_BASILICA]->val4 != sd->bl.id) ) if( sd->sc.getSCE(SC_BASILICA) && (skill_id != HP_BASILICA || sd->sc.getSCE(SC_BASILICA)->val4 != sd->bl.id) )
return; // On basilica only caster can use Basilica again to stop it. return; // On basilica only caster can use Basilica again to stop it.
#endif #endif
@ -13977,7 +13975,7 @@ void clif_parse_OpenVending(int fd, struct map_session_data* sd){
} }
} }
if( sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOROOM ) if( sd->sc.getSCE(SC_NOCHAT) && sd->sc.getSCE(SC_NOCHAT)->val1&MANNER_NOROOM )
return; return;
if( map_getmapflag(sd->bl.m, MF_NOVENDING) ) { if( map_getmapflag(sd->bl.m, MF_NOVENDING) ) {
clif_displaymessage (sd->fd, msg_txt(sd,276)); // "You can't open a shop on this map" clif_displaymessage (sd->fd, msg_txt(sd,276)); // "You can't open a shop on this map"
@ -24753,7 +24751,7 @@ void clif_parse_macro_reporter_ack(int fd, map_session_data *sd) {
return; return;
} }
pc_macro_reporter_process(*sd, *tsd); pc_macro_reporter_process(*tsd, sd->status.account_id);
clif_macro_reporter_status(*sd, MCR_MONITORING); clif_macro_reporter_status(*sd, MCR_MONITORING);
#endif #endif
} }

View File

@ -687,7 +687,7 @@ void clif_emotion(struct block_list *bl,int type);
void clif_talkiebox(struct block_list* bl, const char* talkie); void clif_talkiebox(struct block_list* bl, const char* talkie);
void clif_wedding_effect(struct block_list *bl); void clif_wedding_effect(struct block_list *bl);
void clif_divorced(struct map_session_data* sd, const char* name); void clif_divorced(struct map_session_data* sd, const char* name);
void clif_callpartner(struct map_session_data *sd); void clif_callpartner(struct map_session_data& sd);
void clif_playBGM( struct map_session_data& sd, const char* name ); void clif_playBGM( struct map_session_data& sd, const char* name );
void clif_soundeffect( struct block_list& bl, const char* name, int type, enum send_target target ); void clif_soundeffect( struct block_list& bl, const char* name, int type, enum send_target target );
void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, int target_id, t_tick tick); void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, int target_id, t_tick tick);

View File

@ -583,7 +583,7 @@ static int elemental_ai_sub_timer(s_elemental_data *ed, map_session_data *sd, t_
int master_dist, view_range; int master_dist, view_range;
if( ed->sc.count && ed->sc.data[SC_BLIND] ) if( ed->sc.count && ed->sc.getSCE(SC_BLIND) )
view_range = 3; view_range = 3;
else else
view_range = ed->db->range2; view_range = ed->db->range2;

View File

@ -438,11 +438,11 @@ void mail_send(struct map_session_data *sd, const char *dest_name, const char *t
mail_refresh_remaining_amount(sd); mail_refresh_remaining_amount(sd);
// After calling mail_refresh_remaining_amount the status should always be there // After calling mail_refresh_remaining_amount the status should always be there
if( sd->sc.data[SC_DAILYSENDMAILCNT] == NULL || sd->sc.data[SC_DAILYSENDMAILCNT]->val2 >= battle_config.mail_daily_count ){ if( sd->sc.getSCE(SC_DAILYSENDMAILCNT) == NULL || sd->sc.getSCE(SC_DAILYSENDMAILCNT)->val2 >= battle_config.mail_daily_count ){
clif_Mail_send(sd, WRITE_MAIL_FAILED_CNT); clif_Mail_send(sd, WRITE_MAIL_FAILED_CNT);
return; return;
}else{ }else{
sc_start2( &sd->bl, &sd->bl, SC_DAILYSENDMAILCNT, 100, date_get_dayofyear(), sd->sc.data[SC_DAILYSENDMAILCNT]->val2 + 1, INFINITE_TICK ); sc_start2( &sd->bl, &sd->bl, SC_DAILYSENDMAILCNT, 100, date_get_dayofyear(), sd->sc.getSCE(SC_DAILYSENDMAILCNT)->val2 + 1, INFINITE_TICK );
} }
} }
@ -490,7 +490,7 @@ void mail_refresh_remaining_amount( struct map_session_data* sd ){
nullpo_retv(sd); nullpo_retv(sd);
// If it was not yet started or it was started on another day // If it was not yet started or it was started on another day
if( sd->sc.data[SC_DAILYSENDMAILCNT] == NULL || sd->sc.data[SC_DAILYSENDMAILCNT]->val1 != doy ){ if( sd->sc.getSCE(SC_DAILYSENDMAILCNT) == NULL || sd->sc.getSCE(SC_DAILYSENDMAILCNT)->val1 != doy ){
sc_start2( &sd->bl, &sd->bl, SC_DAILYSENDMAILCNT, 100, doy, 0, INFINITE_TICK ); sc_start2( &sd->bl, &sd->bl, SC_DAILYSENDMAILCNT, 100, doy, 0, INFINITE_TICK );
} }
} }

View File

@ -462,8 +462,8 @@ int map_moveblock(struct block_list *bl, int x1, int y1, t_tick tick)
status_change_end(bl, SC_TATAMIGAESHI); status_change_end(bl, SC_TATAMIGAESHI);
status_change_end(bl, SC_MAGICROD); status_change_end(bl, SC_MAGICROD);
status_change_end(bl, SC_SU_STOOP); status_change_end(bl, SC_SU_STOOP);
if (sc->data[SC_PROPERTYWALK] && if (sc->getSCE(SC_PROPERTYWALK) &&
sc->data[SC_PROPERTYWALK]->val3 >= skill_get_maxcount(sc->data[SC_PROPERTYWALK]->val1,sc->data[SC_PROPERTYWALK]->val2) ) sc->getSCE(SC_PROPERTYWALK)->val3 >= skill_get_maxcount(sc->getSCE(SC_PROPERTYWALK)->val1,sc->getSCE(SC_PROPERTYWALK)->val2) )
status_change_end(bl,SC_PROPERTYWALK); status_change_end(bl,SC_PROPERTYWALK);
} }
} else } else
@ -498,49 +498,49 @@ int map_moveblock(struct block_list *bl, int x1, int y1, t_tick tick)
} }
if (sc && sc->count) { if (sc && sc->count) {
if (sc->data[SC_DANCING]) if (sc->getSCE(SC_DANCING))
skill_unit_move_unit_group(skill_id2group(sc->data[SC_DANCING]->val2), bl->m, x1-x0, y1-y0); skill_unit_move_unit_group(skill_id2group(sc->getSCE(SC_DANCING)->val2), bl->m, x1-x0, y1-y0);
else { else {
if (sc->data[SC_CLOAKING] && sc->data[SC_CLOAKING]->val1 < 3 && !skill_check_cloaking(bl, NULL)) if (sc->getSCE(SC_CLOAKING) && sc->getSCE(SC_CLOAKING)->val1 < 3 && !skill_check_cloaking(bl, NULL))
status_change_end(bl, SC_CLOAKING); status_change_end(bl, SC_CLOAKING);
if (sc->data[SC_WARM]) if (sc->getSCE(SC_WARM))
skill_unit_move_unit_group(skill_id2group(sc->data[SC_WARM]->val4), bl->m, x1-x0, y1-y0); skill_unit_move_unit_group(skill_id2group(sc->getSCE(SC_WARM)->val4), bl->m, x1-x0, y1-y0);
if (sc->data[SC_BANDING]) if (sc->getSCE(SC_BANDING))
skill_unit_move_unit_group(skill_id2group(sc->data[SC_BANDING]->val4), bl->m, x1-x0, y1-y0); skill_unit_move_unit_group(skill_id2group(sc->getSCE(SC_BANDING)->val4), bl->m, x1-x0, y1-y0);
if (sc->data[SC_NEUTRALBARRIER_MASTER]) if (sc->getSCE(SC_NEUTRALBARRIER_MASTER))
skill_unit_move_unit_group(skill_id2group(sc->data[SC_NEUTRALBARRIER_MASTER]->val2), bl->m, x1-x0, y1-y0); skill_unit_move_unit_group(skill_id2group(sc->getSCE(SC_NEUTRALBARRIER_MASTER)->val2), bl->m, x1-x0, y1-y0);
else if (sc->data[SC_STEALTHFIELD_MASTER]) else if (sc->getSCE(SC_STEALTHFIELD_MASTER))
skill_unit_move_unit_group(skill_id2group(sc->data[SC_STEALTHFIELD_MASTER]->val2), bl->m, x1-x0, y1-y0); skill_unit_move_unit_group(skill_id2group(sc->getSCE(SC_STEALTHFIELD_MASTER)->val2), bl->m, x1-x0, y1-y0);
if( sc->data[SC__SHADOWFORM] ) {//Shadow Form Caster Moving if( sc->getSCE(SC__SHADOWFORM) ) {//Shadow Form Caster Moving
struct block_list *d_bl; struct block_list *d_bl;
if( (d_bl = map_id2bl(sc->data[SC__SHADOWFORM]->val2)) == NULL || !check_distance_bl(bl,d_bl,10) ) if( (d_bl = map_id2bl(sc->getSCE(SC__SHADOWFORM)->val2)) == NULL || !check_distance_bl(bl,d_bl,10) )
status_change_end(bl,SC__SHADOWFORM); status_change_end(bl,SC__SHADOWFORM);
} }
if (sc->data[SC_PROPERTYWALK] if (sc->getSCE(SC_PROPERTYWALK)
&& sc->data[SC_PROPERTYWALK]->val3 < skill_get_maxcount(sc->data[SC_PROPERTYWALK]->val1,sc->data[SC_PROPERTYWALK]->val2) && sc->getSCE(SC_PROPERTYWALK)->val3 < skill_get_maxcount(sc->getSCE(SC_PROPERTYWALK)->val1,sc->getSCE(SC_PROPERTYWALK)->val2)
&& map_find_skill_unit_oncell(bl,bl->x,bl->y,SO_ELECTRICWALK,NULL,0) == NULL && map_find_skill_unit_oncell(bl,bl->x,bl->y,SO_ELECTRICWALK,NULL,0) == NULL
&& map_find_skill_unit_oncell(bl,bl->x,bl->y,NPC_ELECTRICWALK,NULL,0) == NULL && map_find_skill_unit_oncell(bl,bl->x,bl->y,NPC_ELECTRICWALK,NULL,0) == NULL
&& map_find_skill_unit_oncell(bl,bl->x,bl->y,SO_FIREWALK,NULL,0) == NULL && map_find_skill_unit_oncell(bl,bl->x,bl->y,SO_FIREWALK,NULL,0) == NULL
&& map_find_skill_unit_oncell(bl,bl->x,bl->y,NPC_FIREWALK,NULL,0) == NULL && map_find_skill_unit_oncell(bl,bl->x,bl->y,NPC_FIREWALK,NULL,0) == NULL
&& skill_unitsetting(bl,sc->data[SC_PROPERTYWALK]->val1,sc->data[SC_PROPERTYWALK]->val2,x0, y0,0)) { && skill_unitsetting(bl,sc->getSCE(SC_PROPERTYWALK)->val1,sc->getSCE(SC_PROPERTYWALK)->val2,x0, y0,0)) {
sc->data[SC_PROPERTYWALK]->val3++; sc->getSCE(SC_PROPERTYWALK)->val3++;
} }
} }
/* Guild Aura Moving */ /* Guild Aura Moving */
if( bl->type == BL_PC && ((TBL_PC*)bl)->state.gmaster_flag ) { if( bl->type == BL_PC && ((TBL_PC*)bl)->state.gmaster_flag ) {
if (sc->data[SC_LEADERSHIP]) if (sc->getSCE(SC_LEADERSHIP))
skill_unit_move_unit_group(skill_id2group(sc->data[SC_LEADERSHIP]->val4), bl->m, x1-x0, y1-y0); skill_unit_move_unit_group(skill_id2group(sc->getSCE(SC_LEADERSHIP)->val4), bl->m, x1-x0, y1-y0);
if (sc->data[SC_GLORYWOUNDS]) if (sc->getSCE(SC_GLORYWOUNDS))
skill_unit_move_unit_group(skill_id2group(sc->data[SC_GLORYWOUNDS]->val4), bl->m, x1-x0, y1-y0); skill_unit_move_unit_group(skill_id2group(sc->getSCE(SC_GLORYWOUNDS)->val4), bl->m, x1-x0, y1-y0);
if (sc->data[SC_SOULCOLD]) if (sc->getSCE(SC_SOULCOLD))
skill_unit_move_unit_group(skill_id2group(sc->data[SC_SOULCOLD]->val4), bl->m, x1-x0, y1-y0); skill_unit_move_unit_group(skill_id2group(sc->getSCE(SC_SOULCOLD)->val4), bl->m, x1-x0, y1-y0);
if (sc->data[SC_HAWKEYES]) if (sc->getSCE(SC_HAWKEYES))
skill_unit_move_unit_group(skill_id2group(sc->data[SC_HAWKEYES]->val4), bl->m, x1-x0, y1-y0); skill_unit_move_unit_group(skill_id2group(sc->getSCE(SC_HAWKEYES)->val4), bl->m, x1-x0, y1-y0);
} }
} }
} else } else
@ -2105,7 +2105,7 @@ int map_quit(struct map_session_data *sd) {
std::bitset<SCF_MAX> &flag = it.second->flag; std::bitset<SCF_MAX> &flag = it.second->flag;
//No need to save infinite status //No need to save infinite status
if (flag[SCF_NOSAVEINFINITE] && sd->sc.data[it.first] && sd->sc.data[it.first]->val4 > 0) { if (flag[SCF_NOSAVEINFINITE] && sd->sc.getSCE(it.first) && sd->sc.getSCE(it.first)->val4 > 0) {
status_change_end(&sd->bl, static_cast<sc_type>(it.first)); status_change_end(&sd->bl, static_cast<sc_type>(it.first));
continue; continue;
} }
@ -3895,7 +3895,6 @@ int parse_console(const char* buf){
int n; int n;
struct map_session_data sd; struct map_session_data sd;
memset(&sd, 0, sizeof(struct map_session_data));
strcpy(sd.status.name, "console"); strcpy(sd.status.name, "console");
if( ( n = sscanf(buf, "%63[^:]:%63[^:]:%11s %6hd %6hd[^\n]", type, command, mapname, &x, &y) ) < 5 ){ if( ( n = sscanf(buf, "%63[^:]:%63[^:]:%11s %6hd %6hd[^\n]", type, command, mapname, &x, &y) ) < 5 ){

View File

@ -573,7 +573,7 @@ bool mob_ksprotected (struct block_list *src, struct block_list *target)
if( md->get_bosstype() == BOSSTYPE_MVP || md->master_id ) if( md->get_bosstype() == BOSSTYPE_MVP || md->master_id )
return false; // MVP, Slaves mobs ignores KS return false; // MVP, Slaves mobs ignores KS
if( (sce = md->sc.data[SC_KSPROTECTED]) == nullptr ) if( (sce = md->sc.getSCE(SC_KSPROTECTED)) == nullptr )
break; // No KS Protected break; // No KS Protected
if( sd->bl.id == sce->val1 || // Same Owner if( sd->bl.id == sce->val1 || // Same Owner
@ -695,8 +695,8 @@ int mob_once_spawn(struct map_session_data* sd, int16 m, int16 x, int16 y, const
md->guardian_data->emblem_id = g->emblem_id; md->guardian_data->emblem_id = g->emblem_id;
memcpy(md->guardian_data->guild_name, g->name, NAME_LENGTH); memcpy(md->guardian_data->guild_name, g->name, NAME_LENGTH);
} }
else if (gc->guild_id) //Guild not yet available, retry in 5. else if (gc->guild_id) // Guild is not yet available, retry after the configured timespan.
add_timer(gettick()+5000,mob_spawn_guardian_sub,md->bl.id,md->guardian_data->guild_id); add_timer(gettick() + battle_config.mob_respawn_time,mob_spawn_guardian_sub,md->bl.id,md->guardian_data->guild_id);
} }
} // end addition [Valaris] } // end addition [Valaris]
@ -914,7 +914,7 @@ int mob_spawn_guardian(const char* mapname, int16 x, int16 y, const char* mobnam
memcpy (md->guardian_data->guild_name, g->name, NAME_LENGTH); memcpy (md->guardian_data->guild_name, g->name, NAME_LENGTH);
md->guardian_data->guardup_lv = guild_checkskill(g,GD_GUARDUP); md->guardian_data->guardup_lv = guild_checkskill(g,GD_GUARDUP);
} else if (md->guardian_data->guild_id) } else if (md->guardian_data->guild_id)
add_timer(gettick()+5000,mob_spawn_guardian_sub,md->bl.id,md->guardian_data->guild_id); add_timer(gettick() + battle_config.mob_respawn_time,mob_spawn_guardian_sub,md->bl.id,md->guardian_data->guild_id);
mob_spawn(md); mob_spawn(md);
return md->bl.id; return md->bl.id;
@ -1073,8 +1073,7 @@ int mob_setdelayspawn(struct mob_data *md)
spawntime = spawntime/100*battle_config.mob_spawn_delay; spawntime = spawntime/100*battle_config.mob_spawn_delay;
} }
if (spawntime < 5000) //Monsters should never respawn faster than within 5 seconds spawntime = u32max(1000, spawntime); //Monsters should never respawn faster than 1 second
spawntime = 5000;
if( md->spawn_timer != INVALID_TIMER ) if( md->spawn_timer != INVALID_TIMER )
delete_timer(md->spawn_timer, mob_delayspawn); delete_timer(md->spawn_timer, mob_delayspawn);
@ -1126,7 +1125,7 @@ int mob_spawn (struct mob_data *md)
{ // retry again later { // retry again later
if( md->spawn_timer != INVALID_TIMER ) if( md->spawn_timer != INVALID_TIMER )
delete_timer(md->spawn_timer, mob_delayspawn); delete_timer(md->spawn_timer, mob_delayspawn);
md->spawn_timer = add_timer(tick+5000,mob_delayspawn,md->bl.id,0); md->spawn_timer = add_timer(tick + battle_config.mob_respawn_time,mob_delayspawn,md->bl.id,0);
return 1; return 1;
} }
} }
@ -1134,7 +1133,7 @@ int mob_spawn (struct mob_data *md)
{ // retry again later (players on sight) { // retry again later (players on sight)
if( md->spawn_timer != INVALID_TIMER ) if( md->spawn_timer != INVALID_TIMER )
delete_timer(md->spawn_timer, mob_delayspawn); delete_timer(md->spawn_timer, mob_delayspawn);
md->spawn_timer = add_timer(tick+5000,mob_delayspawn,md->bl.id,0); md->spawn_timer = add_timer(tick + battle_config.mob_respawn_time,mob_delayspawn,md->bl.id,0);
return 1; return 1;
} }
} }
@ -1709,7 +1708,7 @@ static bool mob_ai_sub_hard(struct mob_data *md, t_tick tick)
return false; return false;
} }
if (md->sc.count && md->sc.data[SC_BLIND]) if (md->sc.count && md->sc.getSCE(SC_BLIND))
view_range = 3; view_range = 3;
else else
view_range = md->db->range2; view_range = md->db->range2;
@ -1744,9 +1743,9 @@ static bool mob_ai_sub_hard(struct mob_data *md, t_tick tick)
{ //Rude attacked check. { //Rude attacked check.
if( !battle_check_range(&md->bl, tbl, md->status.rhw.range) if( !battle_check_range(&md->bl, tbl, md->status.rhw.range)
&& ( //Can't attack back and can't reach back. && ( //Can't attack back and can't reach back.
(!can_move && DIFF_TICK(tick, md->ud.canmove_tick) > 0 && (battle_config.mob_ai&0x2 || md->sc.data[SC_SPIDERWEB] (!can_move && DIFF_TICK(tick, md->ud.canmove_tick) > 0 && (battle_config.mob_ai&0x2 || md->sc.getSCE(SC_SPIDERWEB)
|| md->sc.data[SC_BITE] || md->sc.data[SC_VACUUM_EXTREME] || md->sc.data[SC_THORNSTRAP] || md->sc.getSCE(SC_BITE) || md->sc.getSCE(SC_VACUUM_EXTREME) || md->sc.getSCE(SC_THORNSTRAP)
|| md->sc.data[SC__MANHOLE] // Not yet confirmed if boss will teleport once it can't reach target. || md->sc.getSCE(SC__MANHOLE) // Not yet confirmed if boss will teleport once it can't reach target.
|| md->walktoxy_fail_count > 0) || md->walktoxy_fail_count > 0)
) )
|| !mob_can_reach(md, tbl, md->min_chase) || !mob_can_reach(md, tbl, md->min_chase)
@ -1769,9 +1768,9 @@ static bool mob_ai_sub_hard(struct mob_data *md, t_tick tick)
|| (battle_config.mob_ai&0x2 && !status_check_skilluse(&md->bl, abl, 0, 0)) // Cannot normal attack back to Attacker || (battle_config.mob_ai&0x2 && !status_check_skilluse(&md->bl, abl, 0, 0)) // Cannot normal attack back to Attacker
|| (!battle_check_range(&md->bl, abl, md->status.rhw.range) // Not on Melee Range and ... || (!battle_check_range(&md->bl, abl, md->status.rhw.range) // Not on Melee Range and ...
&& ( // Reach check && ( // Reach check
(!can_move && DIFF_TICK(tick, md->ud.canmove_tick) > 0 && (battle_config.mob_ai&0x2 || md->sc.data[SC_SPIDERWEB] (!can_move && DIFF_TICK(tick, md->ud.canmove_tick) > 0 && (battle_config.mob_ai&0x2 || md->sc.getSCE(SC_SPIDERWEB)
|| md->sc.data[SC_BITE] || md->sc.data[SC_VACUUM_EXTREME] || md->sc.data[SC_THORNSTRAP] || md->sc.getSCE(SC_BITE) || md->sc.getSCE(SC_VACUUM_EXTREME) || md->sc.getSCE(SC_THORNSTRAP)
|| md->sc.data[SC__MANHOLE] // Not yet confirmed if boss will teleport once it can't reach target. || md->sc.getSCE(SC__MANHOLE) // Not yet confirmed if boss will teleport once it can't reach target.
|| md->walktoxy_fail_count > 0) || md->walktoxy_fail_count > 0)
) )
|| !mob_can_reach(md, abl, dist+md->db->range3) || !mob_can_reach(md, abl, dist+md->db->range3)
@ -2456,14 +2455,15 @@ void mob_damage(struct mob_data *md, struct block_list *src, int damage)
* @param drop_modifier: RENEWAL_DROP level modifier * @param drop_modifier: RENEWAL_DROP level modifier
* @return Modified drop rate * @return Modified drop rate
*/ */
int mob_getdroprate(struct block_list *src, std::shared_ptr<s_mob_db> mob, int base_rate, int drop_modifier) int mob_getdroprate(struct block_list *src, std::shared_ptr<s_mob_db> mob, int base_rate, int drop_modifier, mob_data* md)
{ {
int drop_rate = base_rate; int drop_rate = base_rate;
if (battle_config.mob_size_influence) { // Change drops depending on monsters size [Valaris] if (md && battle_config.mob_size_influence) { // Change drops depending on monsters size [Valaris]
if (mob->status.size == SZ_MEDIUM && drop_rate >= 2) unsigned int mob_size = md->special_state.size;
if (mob_size == SZ_MEDIUM && drop_rate >= 2)
drop_rate /= 2; // SZ_MEDIUM actually is small size modification... this is not a bug! drop_rate /= 2; // SZ_MEDIUM actually is small size modification... this is not a bug!
else if (mob->status.size == SZ_BIG) else if (mob_size == SZ_BIG)
drop_rate *= 2; drop_rate *= 2;
} }
@ -2486,8 +2486,8 @@ int mob_getdroprate(struct block_list *src, std::shared_ptr<s_mob_db> mob, int b
drop_rate_bonus += sd->indexed_bonus.dropaddclass[mob->status.class_] + sd->indexed_bonus.dropaddclass[CLASS_ALL]; drop_rate_bonus += sd->indexed_bonus.dropaddclass[mob->status.class_] + sd->indexed_bonus.dropaddclass[CLASS_ALL];
drop_rate_bonus += sd->indexed_bonus.dropaddrace[mob->status.race] + sd->indexed_bonus.dropaddrace[RC_ALL]; drop_rate_bonus += sd->indexed_bonus.dropaddrace[mob->status.race] + sd->indexed_bonus.dropaddrace[RC_ALL];
if (sd->sc.data[SC_ITEMBOOST]) if (sd->sc.getSCE(SC_ITEMBOOST))
drop_rate_bonus += sd->sc.data[SC_ITEMBOOST]->val1; drop_rate_bonus += sd->sc.getSCE(SC_ITEMBOOST)->val1;
int cap; int cap;
@ -2633,15 +2633,15 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
int bonus = 100; //Bonus on top of your share (common to all attackers). int bonus = 100; //Bonus on top of your share (common to all attackers).
int pnum = 0; int pnum = 0;
#ifndef RENEWAL #ifndef RENEWAL
if (md->sc.data[SC_RICHMANKIM]) if (md->sc.getSCE(SC_RICHMANKIM))
bonus += md->sc.data[SC_RICHMANKIM]->val2; bonus += md->sc.getSCE(SC_RICHMANKIM)->val2;
#else #else
if (sd && sd->sc.data[SC_RICHMANKIM]) if (sd && sd->sc.getSCE(SC_RICHMANKIM))
bonus += sd->sc.data[SC_RICHMANKIM]->val2; bonus += sd->sc.getSCE(SC_RICHMANKIM)->val2;
#endif #endif
if(sd) { if(sd) {
temp = status_get_class(&md->bl); temp = status_get_class(&md->bl);
if(sd->sc.data[SC_MIRACLE]) i = 2; //All mobs are Star Targets if(sd->sc.getSCE(SC_MIRACLE)) i = 2; //All mobs are Star Targets
else else
ARR_FIND(0, MAX_PC_FEELHATE, i, temp == sd->hate_mob[i] && ARR_FIND(0, MAX_PC_FEELHATE, i, temp == sd->hate_mob[i] &&
(battle_config.allow_skill_without_day || sg_info[i].day_func())); (battle_config.allow_skill_without_day || sg_info[i].day_func()));
@ -2809,7 +2809,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
if ( it == nullptr ) if ( it == nullptr )
continue; continue;
drop_rate = mob_getdroprate(src, md->db, md->db->dropitem[i].rate, drop_modifier); drop_rate = mob_getdroprate(src, md->db, md->db->dropitem[i].rate, drop_modifier, md);
// attempt to drop the item // attempt to drop the item
if (rnd() % 10000 >= drop_rate) if (rnd() % 10000 >= drop_rate)
@ -3058,7 +3058,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
//Emperium destroyed by script. Discard mvp character. [Skotlex] //Emperium destroyed by script. Discard mvp character. [Skotlex]
mvp_sd = NULL; mvp_sd = NULL;
rebirth = ( md->sc.data[SC_KAIZEL] || md->sc.data[SC_ULTIMATE_S] || (md->sc.data[SC_REBIRTH] && !md->state.rebirth) ); rebirth = ( md->sc.getSCE(SC_KAIZEL) || md->sc.getSCE(SC_ULTIMATE_S) || (md->sc.getSCE(SC_REBIRTH) && !md->state.rebirth) );
if( !rebirth ) { // Only trigger event on final kill if( !rebirth ) { // Only trigger event on final kill
if( src ) { if( src ) {
switch( src->type ) { //allowed type switch( src->type ) { //allowed type
@ -3655,11 +3655,11 @@ int mob_getfriendstatus_sub(struct block_list *bl,va_list ap)
if( cond2==-1 ){ if( cond2==-1 ){
int j; int j;
for(j=SC_COMMON_MIN;j<=SC_COMMON_MAX && !flag;j++){ for(j=SC_COMMON_MIN;j<=SC_COMMON_MAX && !flag;j++){
if ((flag=(md->sc.data[j] != NULL))) //Once an effect was found, break out. [Skotlex] if ((flag=(md->sc.getSCE(j) != NULL))) //Once an effect was found, break out. [Skotlex]
break; break;
} }
}else }else
flag=( md->sc.data[cond2] != NULL ); flag=( md->sc.getSCE(cond2) != NULL );
if( flag^( cond1==MSC_FRIENDSTATUSOFF ) ) if( flag^( cond1==MSC_FRIENDSTATUSOFF ) )
(*fr)=md; (*fr)=md;
@ -3767,10 +3767,10 @@ int mobskill_use(struct mob_data *md, t_tick tick, int event, int64 damage)
flag = 0; flag = 0;
} else if (ms[i]->cond2 == -1) { } else if (ms[i]->cond2 == -1) {
for (j = SC_COMMON_MIN; j <= SC_COMMON_MAX; j++) for (j = SC_COMMON_MIN; j <= SC_COMMON_MAX; j++)
if ((flag = (md->sc.data[j]!=NULL)) != 0) if ((flag = (md->sc.getSCE(j)!=NULL)) != 0)
break; break;
} else { } else {
flag = (md->sc.data[ms[i]->cond2]!=NULL); flag = (md->sc.getSCE(ms[i]->cond2)!=NULL);
} }
flag ^= (ms[i]->cond1 == MSC_MYSTATUSOFF); break; flag ^= (ms[i]->cond1 == MSC_MYSTATUSOFF); break;
case MSC_FRIENDHPLTMAXRATE: // friend HP < maxhp% case MSC_FRIENDHPLTMAXRATE: // friend HP < maxhp%

View File

@ -547,7 +547,7 @@ void mob_add_spawn(uint16 mob_id, const struct spawn_info& new_spawn);
const std::vector<spawn_info> mob_get_spawns(uint16 mob_id); const std::vector<spawn_info> mob_get_spawns(uint16 mob_id);
bool mob_has_spawn(uint16 mob_id); bool mob_has_spawn(uint16 mob_id);
int mob_getdroprate(struct block_list *src, std::shared_ptr<s_mob_db> mob, int base_rate, int drop_modifier); int mob_getdroprate(struct block_list *src, std::shared_ptr<s_mob_db> mob, int base_rate, int drop_modifier, mob_data* md = nullptr);
// MvP Tomb System // MvP Tomb System
int mvptomb_setdelayspawn(struct npc_data *nd); int mvptomb_setdelayspawn(struct npc_data *nd);

View File

@ -1874,7 +1874,7 @@ int npc_touch_areanpc(struct map_session_data* sd, int16 m, int16 x, int16 y, st
switch (nd->subtype) { switch (nd->subtype) {
case NPCTYPE_WARP: case NPCTYPE_WARP:
if ((!nd->trigger_on_hidden && (pc_ishiding(sd) || (sd->sc.count && sd->sc.data[SC_CAMOUFLAGE]))) || pc_isdead(sd)) if ((!nd->trigger_on_hidden && (pc_ishiding(sd) || (sd->sc.count && sd->sc.getSCE(SC_CAMOUFLAGE)))) || pc_isdead(sd))
break; // hidden or dead chars cannot use warps break; // hidden or dead chars cannot use warps
if (!pc_job_can_entermap((enum e_job)sd->status.class_, map_mapindex2mapid(nd->u.warp.mapindex), pc_get_group_level(sd))) if (!pc_job_can_entermap((enum e_job)sd->status.class_, map_mapindex2mapid(nd->u.warp.mapindex), pc_get_group_level(sd)))
break; break;
@ -5118,7 +5118,7 @@ void npc_parse_mob2(struct spawn_data* mob)
static const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath) static const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath)
{ {
int num, mob_id, mob_lv = -1, size = -1, w1count; int num, mob_id, mob_lv = -1, delay = 5000, size = -1, w1count, w4count;
short m, x = 0, y = 0, xs = -1, ys = -1; short m, x = 0, y = 0, xs = -1, ys = -1;
char mapname[MAP_NAME_LENGTH_EXT], mobname[NAME_LENGTH], sprite[NAME_LENGTH]; char mapname[MAP_NAME_LENGTH_EXT], mobname[NAME_LENGTH], sprite[NAME_LENGTH];
struct spawn_data mob, *data; struct spawn_data mob, *data;
@ -5133,7 +5133,7 @@ static const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const c
// w4=<mob id>,<amount>{,<delay1>{,<delay2>{,<event>{,<mob size>{,<mob ai>}}}}} // w4=<mob id>,<amount>{,<delay1>{,<delay2>{,<event>{,<mob size>{,<mob ai>}}}}}
if( ( w1count = sscanf(w1, "%15[^,],%6hd,%6hd,%6hd,%6hd", mapname, &x, &y, &xs, &ys) ) < 1 if( ( w1count = sscanf(w1, "%15[^,],%6hd,%6hd,%6hd,%6hd", mapname, &x, &y, &xs, &ys) ) < 1
|| sscanf(w3, "%23[^,],%11d", mobname, &mob_lv) < 1 || sscanf(w3, "%23[^,],%11d", mobname, &mob_lv) < 1
|| sscanf(w4, "%23[^,],%11d,%11u,%11u,%77[^,],%11d,%11d[^\t\r\n]", sprite, &num, &mob.delay1, &mob.delay2, mob.eventname, &size, &ai) < 2 ) || ( w4count = sscanf(w4, "%23[^,],%11d,%11u,%11u,%77[^,],%11d,%11d[^\t\r\n]", sprite, &num, &delay, &mob.delay2, mob.eventname, &size, &ai) ) < 2 )
{ {
ShowError("npc_parse_mob: Invalid mob definition in file '%s', line '%d'.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4); ShowError("npc_parse_mob: Invalid mob definition in file '%s', line '%d'.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
return strchr(start,'\n');// skip and continue return strchr(start,'\n');// skip and continue
@ -5181,6 +5181,12 @@ static const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const c
return strchr(start,'\n');// skip and continue return strchr(start,'\n');// skip and continue
} }
if (w4count > 2 && delay != 5000 && delay < battle_config.mob_respawn_time) {
ShowWarning("npc_parse_mob: Invalid delay %u for mob ID %d (file '%s', line '%d'), defaulting to 5 seconds.\n", delay, mob_id, filepath, strline(buffer, start - buffer));
mob.delay1 = 5000;
} else
mob.delay1 = delay;
if( mob.state.size > SZ_BIG && size != -1 ) if( mob.state.size > SZ_BIG && size != -1 )
{ {
ShowError("npc_parse_mob: Invalid size number %d for mob ID %d (file '%s', line '%d').\n", mob.state.size, mob_id, filepath, strline(buffer, start - buffer)); ShowError("npc_parse_mob: Invalid size number %d for mob ID %d (file '%s', line '%d').\n", mob.state.size, mob_id, filepath, strline(buffer, start - buffer));

View File

@ -413,6 +413,11 @@ struct PACKET_ZC_ACK_ADD_EXCHANGE_ITEM {
uint8 result; uint8 result;
} __attribute__((packed)); } __attribute__((packed));
struct PACKET_ZC_COUPLENAME {
int16 packetType;
char name[NAME_LENGTH];
} __attribute__((packed));
struct PACKET_EFST_SET_ENTER { struct PACKET_EFST_SET_ENTER {
int16 PacketType; int16 PacketType;
uint32 GID; uint32 GID;
@ -452,6 +457,7 @@ DEFINE_PACKET_HEADER(ZC_BROADCAST2, 0x1c3)
#else #else
DEFINE_PACKET_HEADER(ZC_CHANGE_GUILD, 0x1b4) DEFINE_PACKET_HEADER(ZC_CHANGE_GUILD, 0x1b4)
#endif #endif
DEFINE_PACKET_HEADER(ZC_COUPLENAME, 0x1e6);
DEFINE_PACKET_HEADER(ZC_FRIENDS_LIST, 0x201) DEFINE_PACKET_HEADER(ZC_FRIENDS_LIST, 0x201)
DEFINE_PACKET_HEADER(ZC_NOTIFY_WEAPONITEMLIST, 0x221) DEFINE_PACKET_HEADER(ZC_NOTIFY_WEAPONITEMLIST, 0x221)
DEFINE_PACKET_HEADER(ZC_ACK_WEAPONREFINE, 0x223) DEFINE_PACKET_HEADER(ZC_ACK_WEAPONREFINE, 0x223)

View File

@ -1006,7 +1006,7 @@ int party_skill_check(struct map_session_data *sd, int party_id, uint16 skill_id
break; break;
case MO_COMBOFINISH: //Increase Counter rate of Star Gladiators case MO_COMBOFINISH: //Increase Counter rate of Star Gladiators
if((p_sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR if((p_sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR
&& p_sd->sc.data[SC_READYCOUNTER] && p_sd->sc.getSCE(SC_READYCOUNTER)
&& pc_checkskill(p_sd,SG_FRIEND)) { && pc_checkskill(p_sd,SG_FRIEND)) {
sc_start4(&p_sd->bl,&p_sd->bl,SC_SKILLRATE_UP,100,TK_COUNTER, sc_start4(&p_sd->bl,&p_sd->bl,SC_SKILLRATE_UP,100,TK_COUNTER,
50+50*pc_checkskill(p_sd,SG_FRIEND), //+100/150/200% rate 50+50*pc_checkskill(p_sd,SG_FRIEND), //+100/150/200% rate

View File

@ -916,7 +916,7 @@ int pc_addsoulball(map_session_data *sd, int max)
status_change *sc = status_get_sc(&sd->bl); status_change *sc = status_get_sc(&sd->bl);
if (sc == nullptr || sc->data[SC_SOULENERGY] == nullptr) { if (sc == nullptr || sc->getSCE(SC_SOULENERGY) == nullptr) {
sc_start(&sd->bl, &sd->bl, SC_SOULENERGY, 100, 0, skill_get_time2(SP_SOULCOLLECT, 1)); sc_start(&sd->bl, &sd->bl, SC_SOULENERGY, 100, 0, skill_get_time2(SP_SOULCOLLECT, 1));
sd->soulball = 0; sd->soulball = 0;
} }
@ -949,14 +949,14 @@ int pc_delsoulball(map_session_data *sd, int count, bool type)
status_change *sc = status_get_sc(&sd->bl); status_change *sc = status_get_sc(&sd->bl);
if (sd->soulball <= 0 || sc == nullptr || sc->data[SC_SOULENERGY] == nullptr) { if (sd->soulball <= 0 || sc == nullptr || sc->getSCE(SC_SOULENERGY) == nullptr) {
sd->soulball = 0; sd->soulball = 0;
}else{ }else{
sd->soulball -= cap_value(count, 0, sd->soulball); sd->soulball -= cap_value(count, 0, sd->soulball);
if (sd->soulball == 0) if (sd->soulball == 0)
status_change_end(&sd->bl, SC_SOULENERGY); status_change_end(&sd->bl, SC_SOULENERGY);
else else
sc->data[SC_SOULENERGY]->val1 = sd->soulball; sc->getSCE(SC_SOULENERGY)->val1 = sd->soulball;
} }
if (!type) if (!type)
@ -1307,7 +1307,7 @@ void pc_makesavestatus(struct map_session_data *sd) {
#else #else
sd->status.option = sd->sc.option&(OPTION_INVISIBLE|OPTION_CART|OPTION_FALCON|OPTION_RIDING|OPTION_DRAGON|OPTION_WUG|OPTION_WUGRIDER|OPTION_MADOGEAR); sd->status.option = sd->sc.option&(OPTION_INVISIBLE|OPTION_CART|OPTION_FALCON|OPTION_RIDING|OPTION_DRAGON|OPTION_WUG|OPTION_WUGRIDER|OPTION_MADOGEAR);
#endif #endif
if (sd->sc.data[SC_JAILED]) { //When Jailed, do not move last point. if (sd->sc.getSCE(SC_JAILED)) { //When Jailed, do not move last point.
if(pc_isdead(sd)){ if(pc_isdead(sd)){
pc_setrestartvalue(sd, 0); pc_setrestartvalue(sd, 0);
} else { } else {
@ -1825,24 +1825,24 @@ uint8 pc_isequip(struct map_session_data *sd,int n)
} }
if (sd->sc.count) { if (sd->sc.count) {
if(item->equip & EQP_ARMS && item->type == IT_WEAPON && sd->sc.data[SC_STRIPWEAPON]) // Also works with left-hand weapons [DracoRPG] if(item->equip & EQP_ARMS && item->type == IT_WEAPON && sd->sc.getSCE(SC_STRIPWEAPON)) // Also works with left-hand weapons [DracoRPG]
return ITEM_EQUIP_ACK_FAIL; return ITEM_EQUIP_ACK_FAIL;
if(item->equip & EQP_SHIELD && item->type == IT_ARMOR && sd->sc.data[SC_STRIPSHIELD]) if(item->equip & EQP_SHIELD && item->type == IT_ARMOR && sd->sc.getSCE(SC_STRIPSHIELD))
return ITEM_EQUIP_ACK_FAIL; return ITEM_EQUIP_ACK_FAIL;
if(item->equip & EQP_ARMOR && sd->sc.data[SC_STRIPARMOR]) if(item->equip & EQP_ARMOR && sd->sc.getSCE(SC_STRIPARMOR))
return ITEM_EQUIP_ACK_FAIL; return ITEM_EQUIP_ACK_FAIL;
if(item->equip & EQP_HEAD_TOP && sd->sc.data[SC_STRIPHELM]) if(item->equip & EQP_HEAD_TOP && sd->sc.getSCE(SC_STRIPHELM))
return ITEM_EQUIP_ACK_FAIL; return ITEM_EQUIP_ACK_FAIL;
if(item->equip & EQP_ACC && sd->sc.data[SC__STRIPACCESSORY]) if(item->equip & EQP_ACC && sd->sc.getSCE(SC__STRIPACCESSORY))
return ITEM_EQUIP_ACK_FAIL; return ITEM_EQUIP_ACK_FAIL;
if (item->equip & EQP_ARMS && sd->sc.data[SC__WEAKNESS]) if (item->equip & EQP_ARMS && sd->sc.getSCE(SC__WEAKNESS))
return ITEM_EQUIP_ACK_FAIL; return ITEM_EQUIP_ACK_FAIL;
if (item->equip & EQP_SHADOW_GEAR && sd->sc.data[SC_SHADOW_STRIP]) if (item->equip & EQP_SHADOW_GEAR && sd->sc.getSCE(SC_SHADOW_STRIP))
return ITEM_EQUIP_ACK_FAIL; return ITEM_EQUIP_ACK_FAIL;
if(item->equip && (sd->sc.data[SC_KYOUGAKU] || sd->sc.data[SC_SUHIDE])) if(item->equip && (sd->sc.getSCE(SC_KYOUGAKU) || sd->sc.getSCE(SC_SUHIDE)))
return ITEM_EQUIP_ACK_FAIL; return ITEM_EQUIP_ACK_FAIL;
if (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_SUPERNOVICE) { if (sd->sc.getSCE(SC_SPIRIT) && sd->sc.getSCE(SC_SPIRIT)->val2 == SL_SUPERNOVICE) {
//Spirit of Super Novice equip bonuses. [Skotlex] //Spirit of Super Novice equip bonuses. [Skotlex]
if (sd->status.base_level > 90 && item->equip & EQP_HELM) if (sd->status.base_level > 90 && item->equip & EQP_HELM)
return ITEM_EQUIP_ACK_OK; //Can equip all helms return ITEM_EQUIP_ACK_OK; //Can equip all helms
@ -2528,7 +2528,7 @@ void pc_calc_skilltree(struct map_session_data *sd)
if (!sd->status.skill[sk_idx].lv && ( if (!sd->status.skill[sk_idx].lv && (
(skill->inf2[INF2_ISQUEST] && !battle_config.quest_skill_learn) || (skill->inf2[INF2_ISQUEST] && !battle_config.quest_skill_learn) ||
skill->inf2[INF2_ISWEDDING] || skill->inf2[INF2_ISWEDDING] ||
(skill->inf2[INF2_ISSPIRIT] && !sd->sc.data[SC_SPIRIT]) (skill->inf2[INF2_ISSPIRIT] && !sd->sc.getSCE(SC_SPIRIT))
)) ))
continue; //Cannot be learned via normal means. Note this check DOES allows raising already known skills. continue; //Cannot be learned via normal means. Note this check DOES allows raising already known skills.
@ -2575,7 +2575,7 @@ void pc_calc_skilltree(struct map_session_data *sd)
} }
// Enable Bard/Dancer spirit linked skills. // Enable Bard/Dancer spirit linked skills.
if (sd->sc.count && sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_BARDDANCER) { if (sd->sc.count && sd->sc.getSCE(SC_SPIRIT) && sd->sc.getSCE(SC_SPIRIT)->val2 == SL_BARDDANCER) {
std::vector<std::vector<uint16>> linked_skills = { { BA_WHISTLE, DC_HUMMING }, std::vector<std::vector<uint16>> linked_skills = { { BA_WHISTLE, DC_HUMMING },
{ BA_ASSASSINCROSS, DC_DONTFORGETME }, { BA_ASSASSINCROSS, DC_DONTFORGETME },
{ BA_POEMBRAGI, DC_FORTUNEKISS }, { BA_POEMBRAGI, DC_FORTUNEKISS },
@ -2655,7 +2655,7 @@ static void pc_check_skilltree(struct map_session_data *sd)
if( !sd->status.skill[sk_idx].lv && ( if( !sd->status.skill[sk_idx].lv && (
(skill->inf2[INF2_ISQUEST] && !battle_config.quest_skill_learn) || (skill->inf2[INF2_ISQUEST] && !battle_config.quest_skill_learn) ||
skill->inf2[INF2_ISWEDDING] || skill->inf2[INF2_ISWEDDING] ||
(skill->inf2[INF2_ISSPIRIT] && !sd->sc.data[SC_SPIRIT]) (skill->inf2[INF2_ISSPIRIT] && !sd->sc.getSCE(SC_SPIRIT))
) ) ) )
continue; //Cannot be learned via normal means. continue; //Cannot be learned via normal means.
@ -2816,7 +2816,7 @@ void pc_updateweightstatus(struct map_session_data *sd)
nullpo_retv(sd); nullpo_retv(sd);
old_overweight = (sd->sc.data[SC_WEIGHT90]) ? 2 : (sd->sc.data[SC_WEIGHT50]) ? 1 : 0; old_overweight = (sd->sc.getSCE(SC_WEIGHT90)) ? 2 : (sd->sc.getSCE(SC_WEIGHT50)) ? 1 : 0;
#ifdef RENEWAL #ifdef RENEWAL
new_overweight = (pc_is90overweight(sd)) ? 2 : (pc_is70overweight(sd)) ? 1 : 0; new_overweight = (pc_is90overweight(sd)) ? 2 : (pc_is70overweight(sd)) ? 1 : 0;
#else #else
@ -6212,7 +6212,7 @@ int pc_useitem(struct map_session_data *sd,int n)
/* Items with delayed consume are not meant to work while in mounts except reins of mount(12622) */ /* Items with delayed consume are not meant to work while in mounts except reins of mount(12622) */
if( id->flag.delay_consume > 0 ) { if( id->flag.delay_consume > 0 ) {
if( nameid != ITEMID_REINS_OF_MOUNT && sd->sc.data[SC_ALL_RIDING] ) if( nameid != ITEMID_REINS_OF_MOUNT && sd->sc.getSCE(SC_ALL_RIDING) )
return 0; return 0;
else if( pc_issit(sd) ) else if( pc_issit(sd) )
return 0; return 0;
@ -6612,8 +6612,8 @@ int pc_steal_coin(struct map_session_data *sd,struct block_list *target)
md = (TBL_MOB*)target; md = (TBL_MOB*)target;
target_lv = status_get_lv(target); target_lv = status_get_lv(target);
if (md->state.steal_coin_flag || md->sc.data[SC_STONE] || md->sc.data[SC_FREEZE] || md->sc.data[SC_HANDICAPSTATE_FROSTBITE] || if (md->state.steal_coin_flag || md->sc.getSCE(SC_STONE) || md->sc.getSCE(SC_FREEZE) || md->sc.getSCE(SC_HANDICAPSTATE_FROSTBITE) ||
md->sc.data[SC_HANDICAPSTATE_SWOONING] || md->sc.data[SC_HANDICAPSTATE_LIGHTNINGSTRIKE] || md->sc.data[SC_HANDICAPSTATE_CRYSTALLIZATION] || md->sc.getSCE(SC_HANDICAPSTATE_SWOONING) || md->sc.getSCE(SC_HANDICAPSTATE_LIGHTNINGSTRIKE) || md->sc.getSCE(SC_HANDICAPSTATE_CRYSTALLIZATION) ||
status_bl_has_mode(target,MD_STATUSIMMUNE) || util::vector_exists(status_get_race2(&md->bl), RC2_TREASURE)) status_bl_has_mode(target,MD_STATUSIMMUNE) || util::vector_exists(status_get_race2(&md->bl), RC2_TREASURE))
return 0; return 0;
@ -6691,12 +6691,12 @@ enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, in
return SETPOS_MAPINDEX; // You may not get out! return SETPOS_MAPINDEX; // You may not get out!
for (const auto &it : status_db) { for (const auto &it : status_db) {
if (sc->data[it.first]) { if (sc->getSCE(it.first)) {
if (it.second->flag[SCF_REMOVEONMAPWARP]) if (it.second->flag[SCF_REMOVEONMAPWARP])
status_change_end(&sd->bl, static_cast<sc_type>(it.first)); status_change_end(&sd->bl, static_cast<sc_type>(it.first));
if (it.second->flag[SCF_RESTARTONMAPWARP] && it.second->skill_id > 0) { if (it.second->flag[SCF_RESTARTONMAPWARP] && it.second->skill_id > 0) {
status_change_entry *sce = sd->sc.data[it.first]; status_change_entry *sce = sd->sc.getSCE(it.first);
if (sce->timer != INVALID_TIMER) if (sce->timer != INVALID_TIMER)
delete_timer(sce->timer, status_change_timer); delete_timer(sce->timer, status_change_timer);
@ -6988,7 +6988,7 @@ int pc_get_skillcooldown(struct map_session_data *sd, uint16 skill_id, uint16 sk
if (skill_id == SJ_NOVAEXPLOSING) { if (skill_id == SJ_NOVAEXPLOSING) {
struct status_change *sc = status_get_sc(&sd->bl); struct status_change *sc = status_get_sc(&sd->bl);
if (sc && sc->data[SC_DIMENSION]) if (sc && sc->getSCE(SC_DIMENSION))
return 0; return 0;
} }
@ -7135,12 +7135,12 @@ static void pc_checkallowskill(struct map_session_data *sd)
if (flag[SCF_REQUIREWEAPON]) { // Skills requiring specific weapon types if (flag[SCF_REQUIREWEAPON]) { // Skills requiring specific weapon types
if (status == SC_DANCING && !battle_config.dancing_weaponswitch_fix) if (status == SC_DANCING && !battle_config.dancing_weaponswitch_fix)
continue; continue;
if (sd->sc.data[status] && !pc_check_weapontype(sd, skill_get_weapontype(it.second->skill_id))) if (sd->sc.getSCE(status) && !pc_check_weapontype(sd, skill_get_weapontype(it.second->skill_id)))
status_change_end(&sd->bl, status); status_change_end(&sd->bl, status);
} }
if (flag[SCF_REQUIRESHIELD]) { // Skills requiring a shield if (flag[SCF_REQUIRESHIELD]) { // Skills requiring a shield
if (sd->sc.data[status] && sd->status.shield <= 0) if (sd->sc.getSCE(status) && sd->status.shield <= 0)
status_change_end(&sd->bl, status); status_change_end(&sd->bl, status);
} }
} }
@ -8074,10 +8074,10 @@ static void pc_calcexp(struct map_session_data *sd, t_exp *base_exp, t_exp *job_
} }
// Give EXPBOOST for quests even if src is NULL. // Give EXPBOOST for quests even if src is NULL.
if (sd->sc.data[SC_EXPBOOST]) { if (sd->sc.getSCE(SC_EXPBOOST)) {
bonus += sd->sc.data[SC_EXPBOOST]->val1; bonus += sd->sc.getSCE(SC_EXPBOOST)->val1;
if (battle_config.vip_bm_increase && pc_isvip(sd)) // Increase Battle Manual EXP rate for VIP if (battle_config.vip_bm_increase && pc_isvip(sd)) // Increase Battle Manual EXP rate for VIP
bonus += (sd->sc.data[SC_EXPBOOST]->val1 / battle_config.vip_bm_increase); bonus += (sd->sc.getSCE(SC_EXPBOOST)->val1 / battle_config.vip_bm_increase);
} }
if (*base_exp) { if (*base_exp) {
@ -8086,8 +8086,8 @@ static void pc_calcexp(struct map_session_data *sd, t_exp *base_exp, t_exp *job_
} }
// Give JEXPBOOST for quests even if src is NULL. // Give JEXPBOOST for quests even if src is NULL.
if (sd->sc.data[SC_JEXPBOOST]) if (sd->sc.getSCE(SC_JEXPBOOST))
bonus += sd->sc.data[SC_JEXPBOOST]->val1; bonus += sd->sc.getSCE(SC_JEXPBOOST)->val1;
if (*job_exp) { if (*job_exp) {
t_exp exp = (t_exp)(*job_exp + ((double)*job_exp * ((bonus + vip_bonus_job) / 100.))); t_exp exp = (t_exp)(*job_exp + ((double)*job_exp * ((bonus + vip_bonus_job) / 100.)));
@ -9137,7 +9137,7 @@ int pc_resetskill(struct map_session_data* sd, int flag)
if( i&OPTION_CART && pc_checkskill(sd, MC_PUSHCART) ) if( i&OPTION_CART && pc_checkskill(sd, MC_PUSHCART) )
i &= ~OPTION_CART; i &= ~OPTION_CART;
#else #else
if( sd->sc.data[SC_PUSH_CART] ) if( sd->sc.getSCE(SC_PUSH_CART) )
pc_setcart(sd, 0); pc_setcart(sd, 0);
#endif #endif
if( i != sd->sc.option ) if( i != sd->sc.option )
@ -9146,9 +9146,9 @@ int pc_resetskill(struct map_session_data* sd, int flag)
if( hom_is_active(sd->hd) && pc_checkskill(sd, AM_CALLHOMUN) ) if( hom_is_active(sd->hd) && pc_checkskill(sd, AM_CALLHOMUN) )
hom_vaporize(sd, HOM_ST_ACTIVE); hom_vaporize(sd, HOM_ST_ACTIVE);
if (sd->sc.data[SC_SPRITEMABLE] && pc_checkskill(sd, SU_SPRITEMABLE)) if (sd->sc.getSCE(SC_SPRITEMABLE) && pc_checkskill(sd, SU_SPRITEMABLE))
status_change_end(&sd->bl, SC_SPRITEMABLE); status_change_end(&sd->bl, SC_SPRITEMABLE);
if (sd->sc.data[SC_SOULATTACK] && pc_checkskill(sd, SU_SOULATTACK)) if (sd->sc.getSCE(SC_SOULATTACK) && pc_checkskill(sd, SU_SOULATTACK))
status_change_end(&sd->bl, SC_SOULATTACK); status_change_end(&sd->bl, SC_SOULATTACK);
} }
@ -9833,15 +9833,15 @@ bool pc_revive_item(struct map_session_data *sd) {
if (!pc_isdead(sd) || sd->respawn_tid != INVALID_TIMER) if (!pc_isdead(sd) || sd->respawn_tid != INVALID_TIMER)
return false; return false;
if (sd->sc.data[SC_HELLPOWER]) // Cannot resurrect while under the effect of SC_HELLPOWER. if (sd->sc.getSCE(SC_HELLPOWER)) // Cannot resurrect while under the effect of SC_HELLPOWER.
return false; return false;
int16 item_position = itemdb_group.item_exists_pc(sd, IG_TOKEN_OF_SIEGFRIED); int16 item_position = itemdb_group.item_exists_pc(sd, IG_TOKEN_OF_SIEGFRIED);
uint8 hp = 100, sp = 100; uint8 hp = 100, sp = 100;
if (item_position < 0) { if (item_position < 0) {
if (sd->sc.data[SC_LIGHT_OF_REGENE]) { if (sd->sc.getSCE(SC_LIGHT_OF_REGENE)) {
hp = sd->sc.data[SC_LIGHT_OF_REGENE]->val2; hp = sd->sc.getSCE(SC_LIGHT_OF_REGENE)->val2;
sp = 0; sp = 0;
} }
else else
@ -10357,7 +10357,7 @@ int pc_itemheal(struct map_session_data *sd, t_itemid itemid, int hp, int sp)
// A potion produced by an Alchemist in the Fame Top 10 gets +50% effect [DracoRPG] // A potion produced by an Alchemist in the Fame Top 10 gets +50% effect [DracoRPG]
if (potion_flag == 2) { if (potion_flag == 2) {
bonus += bonus * 50 / 100; bonus += bonus * 50 / 100;
if (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_ROGUE) if (sd->sc.getSCE(SC_SPIRIT) && sd->sc.getSCE(SC_SPIRIT)->val2 == SL_ROGUE)
bonus += bonus; // Receive an additional +100% effect from ranked potions to HP only bonus += bonus; // Receive an additional +100% effect from ranked potions to HP only
} }
//All item bonuses. //All item bonuses.
@ -10372,16 +10372,16 @@ int pc_itemheal(struct map_session_data *sd, t_itemid itemid, int hp, int sp)
} }
} }
// Recovery Potion // Recovery Potion
if (sd->sc.data[SC_INCHEALRATE]) if (sd->sc.getSCE(SC_INCHEALRATE))
bonus += bonus * sd->sc.data[SC_INCHEALRATE]->val1 / 100; bonus += bonus * sd->sc.getSCE(SC_INCHEALRATE)->val1 / 100;
// 2014 Halloween Event : Pumpkin Bonus // 2014 Halloween Event : Pumpkin Bonus
if (sd->sc.data[SC_MTF_PUMPKIN]) { if (sd->sc.getSCE(SC_MTF_PUMPKIN)) {
if (itemid == ITEMID_PUMPKIN) if (itemid == ITEMID_PUMPKIN)
bonus += bonus * sd->sc.data[SC_MTF_PUMPKIN]->val1 / 100; bonus += bonus * sd->sc.getSCE(SC_MTF_PUMPKIN)->val1 / 100;
else if (itemid == ITEMID_COOKIE_BAT) else if (itemid == ITEMID_COOKIE_BAT)
bonus += sd->sc.data[SC_MTF_PUMPKIN]->val2; bonus += sd->sc.getSCE(SC_MTF_PUMPKIN)->val2;
} }
if (sd->sc.data[SC_VITALIZE_POTION]) if (sd->sc.getSCE(SC_VITALIZE_POTION))
bonus += bonus * 10 / 100; bonus += bonus * 10 / 100;
tmp = hp * bonus / 100; // Overflow check tmp = hp * bonus / 100; // Overflow check
@ -10412,26 +10412,26 @@ int pc_itemheal(struct map_session_data *sd, t_itemid itemid, int hp, int sp)
} }
if (sd->sc.count) { if (sd->sc.count) {
// Critical Wound and Death Hurt stack // Critical Wound and Death Hurt stack
if (sd->sc.data[SC_CRITICALWOUND]) if (sd->sc.getSCE(SC_CRITICALWOUND))
penalty += sd->sc.data[SC_CRITICALWOUND]->val2; penalty += sd->sc.getSCE(SC_CRITICALWOUND)->val2;
if (sd->sc.data[SC_DEATHHURT] && sd->sc.data[SC_DEATHHURT]->val3 == 1) if (sd->sc.getSCE(SC_DEATHHURT) && sd->sc.getSCE(SC_DEATHHURT)->val3 == 1)
penalty += 20; penalty += 20;
if (sd->sc.data[SC_NORECOVER_STATE]) if (sd->sc.getSCE(SC_NORECOVER_STATE))
penalty = 100; penalty = 100;
if (sd->sc.data[SC_VITALITYACTIVATION]) if (sd->sc.getSCE(SC_VITALITYACTIVATION))
hp += hp / 2; // 1.5 times hp += hp / 2; // 1.5 times
if (sd->sc.data[SC_WATER_INSIGNIA] && sd->sc.data[SC_WATER_INSIGNIA]->val1 == 2) { if (sd->sc.getSCE(SC_WATER_INSIGNIA) && sd->sc.getSCE(SC_WATER_INSIGNIA)->val1 == 2) {
hp += hp / 10; hp += hp / 10;
sp += sp / 10; sp += sp / 10;
} }
#ifdef RENEWAL #ifdef RENEWAL
if (sd->sc.data[SC_APPLEIDUN]) if (sd->sc.getSCE(SC_APPLEIDUN))
hp += sd->sc.data[SC_APPLEIDUN]->val3 / 100; hp += sd->sc.getSCE(SC_APPLEIDUN)->val3 / 100;
#endif #endif
if (penalty > 0) { if (penalty > 0) {
@ -10440,10 +10440,10 @@ int pc_itemheal(struct map_session_data *sd, t_itemid itemid, int hp, int sp)
} }
#ifdef RENEWAL #ifdef RENEWAL
if (sd->sc.data[SC_EXTREMITYFIST2]) if (sd->sc.getSCE(SC_EXTREMITYFIST2))
sp = 0; sp = 0;
#endif #endif
if (sd->sc.data[SC_BITESCAR]) if (sd->sc.getSCE(SC_BITESCAR))
hp = 0; hp = 0;
} }
@ -10695,7 +10695,7 @@ bool pc_jobchange(struct map_session_data *sd,int job, char upper)
if( i&OPTION_CART && !pc_checkskill(sd, MC_PUSHCART) ) if( i&OPTION_CART && !pc_checkskill(sd, MC_PUSHCART) )
i&=~OPTION_CART; i&=~OPTION_CART;
#else #else
if( sd->sc.data[SC_PUSH_CART] && !pc_checkskill(sd, MC_PUSHCART) ) if( sd->sc.getSCE(SC_PUSH_CART) && !pc_checkskill(sd, MC_PUSHCART) )
pc_setcart(sd, 0); pc_setcart(sd, 0);
#endif #endif
if(i != sd->sc.option) if(i != sd->sc.option)
@ -10704,11 +10704,11 @@ bool pc_jobchange(struct map_session_data *sd,int job, char upper)
if(hom_is_active(sd->hd) && !pc_checkskill(sd, AM_CALLHOMUN)) if(hom_is_active(sd->hd) && !pc_checkskill(sd, AM_CALLHOMUN))
hom_vaporize(sd, HOM_ST_ACTIVE); hom_vaporize(sd, HOM_ST_ACTIVE);
if (sd->sc.data[SC_SPRITEMABLE] && !pc_checkskill(sd, SU_SPRITEMABLE)) if (sd->sc.getSCE(SC_SPRITEMABLE) && !pc_checkskill(sd, SU_SPRITEMABLE))
status_change_end(&sd->bl, SC_SPRITEMABLE); status_change_end(&sd->bl, SC_SPRITEMABLE);
if (sd->sc.data[SC_SOULATTACK] && !pc_checkskill(sd, SU_SOULATTACK)) if (sd->sc.getSCE(SC_SOULATTACK) && !pc_checkskill(sd, SU_SOULATTACK))
status_change_end(&sd->bl, SC_SOULATTACK); status_change_end(&sd->bl, SC_SOULATTACK);
if( sd->sc.data[SC_SPIRIT] ){ if( sd->sc.getSCE(SC_SPIRIT) ){
status_change_end( &sd->bl, SC_SPIRIT ); status_change_end( &sd->bl, SC_SPIRIT );
} }
@ -10931,13 +10931,13 @@ bool pc_setcart(struct map_session_data *sd,int type) {
switch( type ) { switch( type ) {
case 0: case 0:
if( !sd->sc.data[SC_PUSH_CART] ) if( !sd->sc.getSCE(SC_PUSH_CART) )
return 0; return 0;
status_change_end(&sd->bl,SC_PUSH_CART); status_change_end(&sd->bl,SC_PUSH_CART);
clif_clearcart(sd->fd); clif_clearcart(sd->fd);
break; break;
default:/* everything else is an allowed ID so we can move on */ default:/* everything else is an allowed ID so we can move on */
if( !sd->sc.data[SC_PUSH_CART] ) { /* first time, so fill cart data */ if( !sd->sc.getSCE(SC_PUSH_CART) ) { /* first time, so fill cart data */
clif_cartlist(sd); clif_cartlist(sd);
status_calc_cart_weight(sd, (e_status_calc_weight_opt)(CALCWT_ITEM|CALCWT_MAXBONUS|CALCWT_CARTSTATE)); status_calc_cart_weight(sd, (e_status_calc_weight_opt)(CALCWT_ITEM|CALCWT_MAXBONUS|CALCWT_CARTSTATE));
} }
@ -10977,7 +10977,7 @@ void pc_setfalcon(struct map_session_data* sd, int flag)
*------------------------------------------*/ *------------------------------------------*/
void pc_setriding(struct map_session_data* sd, int flag) void pc_setriding(struct map_session_data* sd, int flag)
{ {
if( sd->sc.data[SC_ALL_RIDING] ) if( sd->sc.getSCE(SC_ALL_RIDING) )
return; return;
if( flag ){ if( flag ){
@ -11723,7 +11723,7 @@ bool pc_equipitem(struct map_session_data *sd,short n,int req_pos,bool equipswit
} }
return false; return false;
} }
if( sd->sc.count && (sd->sc.cant.equip || (sd->sc.data[SC_PYROCLASTIC] && sd->inventory_data[n]->type == IT_WEAPON)) ) { if( sd->sc.count && (sd->sc.cant.equip || (sd->sc.getSCE(SC_PYROCLASTIC) && sd->inventory_data[n]->type == IT_WEAPON)) ) {
if( equipswitch ){ if( equipswitch ){
clif_equipswitch_add( sd, n, req_pos, ITEM_EQUIP_ACK_FAIL ); clif_equipswitch_add( sd, n, req_pos, ITEM_EQUIP_ACK_FAIL );
}else{ }else{
@ -12001,7 +12001,7 @@ static void pc_unequipitem_sub(struct map_session_data *sd, int n, int flag) {
status_calc_pc(sd, SCO_FORCE); status_calc_pc(sd, SCO_FORCE);
} }
if (sd->sc.data[SC_SIGNUMCRUCIS] && !battle_check_undead(sd->battle_status.race, sd->battle_status.def_ele)) if (sd->sc.getSCE(SC_SIGNUMCRUCIS) && !battle_check_undead(sd->battle_status.race, sd->battle_status.def_ele))
status_change_end(&sd->bl, SC_SIGNUMCRUCIS); status_change_end(&sd->bl, SC_SIGNUMCRUCIS);
//OnUnEquip script [Skotlex] //OnUnEquip script [Skotlex]
@ -12055,7 +12055,7 @@ bool pc_unequipitem(struct map_session_data *sd, int n, int flag) {
} }
// status change that makes player cannot unequip equipment // status change that makes player cannot unequip equipment
if (!(flag&2) && sd->sc.count &&( sd->sc.cant.unequip || if (!(flag&2) && sd->sc.count &&( sd->sc.cant.unequip ||
(sd->sc.data[SC_PYROCLASTIC] && sd->inventory_data[n]->type == IT_WEAPON))) // can't switch weapon (sd->sc.getSCE(SC_PYROCLASTIC) && sd->inventory_data[n]->type == IT_WEAPON))) // can't switch weapon
{ {
clif_unequipitemack(sd,n,0,0); clif_unequipitemack(sd,n,0,0);
return false; return false;
@ -12753,7 +12753,7 @@ bool pc_setstand(struct map_session_data *sd, bool force){
// Cannot stand yet // Cannot stand yet
// TODO: Move to SCS_NOSTAND [Cydh] // TODO: Move to SCS_NOSTAND [Cydh]
if (!force && (sd->sc.data[SC_SITDOWN_FORCE] || sd->sc.data[SC_BANANA_BOMB_SITDOWN])) if (!force && (sd->sc.getSCE(SC_SITDOWN_FORCE) || sd->sc.getSCE(SC_BANANA_BOMB_SITDOWN)))
return false; return false;
status_change_end(&sd->bl, SC_TENSIONRELAX); status_change_end(&sd->bl, SC_TENSIONRELAX);
@ -12776,7 +12776,7 @@ bool pc_setstand(struct map_session_data *sd, bool force){
* @param heat: Amount of Heat to adjust * @param heat: Amount of Heat to adjust
**/ **/
void pc_overheat(map_session_data &sd, int16 heat) { void pc_overheat(map_session_data &sd, int16 heat) {
status_change_entry *sce = sd.sc.data[SC_OVERHEAT_LIMITPOINT]; status_change_entry *sce = sd.sc.getSCE(SC_OVERHEAT_LIMITPOINT);
if (sce) { if (sce) {
sce->val1 += heat; sce->val1 += heat;
@ -14270,8 +14270,8 @@ uint8 pc_itemcd_check(struct map_session_data *sd, struct item_data *id, t_tick
return pc_itemcd_add(sd, id, tick, n); return pc_itemcd_add(sd, id, tick, n);
// Send reply of delay remains // Send reply of delay remains
if (sc->data[id->delay.sc]) { if (sc->getSCE(id->delay.sc)) {
const struct TimerData *timer = get_timer(sc->data[id->delay.sc]->timer); const struct TimerData *timer = get_timer(sc->getSCE(id->delay.sc)->timer);
clif_msg_value(sd, ITEM_REUSE_LIMIT, (int)(timer ? DIFF_TICK(timer->tick, tick) / 1000 : 99)); clif_msg_value(sd, ITEM_REUSE_LIMIT, (int)(timer ? DIFF_TICK(timer->tick, tick) / 1000 : 99));
return 1; return 1;
} }
@ -14379,8 +14379,8 @@ void pc_scdata_received(struct map_session_data *sd) {
status_calc_cart_weight(sd, (e_status_calc_weight_opt)(CALCWT_ITEM|CALCWT_MAXBONUS|CALCWT_CARTSTATE)); status_calc_cart_weight(sd, (e_status_calc_weight_opt)(CALCWT_ITEM|CALCWT_MAXBONUS|CALCWT_CARTSTATE));
} }
if (sd->sc.data[SC_SOULENERGY]) if (sd->sc.getSCE(SC_SOULENERGY))
sd->soulball = sd->sc.data[SC_SOULENERGY]->val1; sd->soulball = sd->sc.getSCE(SC_SOULENERGY)->val1;
} }
/** /**
@ -14784,10 +14784,10 @@ void pc_cell_basilica(struct map_session_data *sd) {
#endif #endif
if (!map_getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKBASILICA)) { if (!map_getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKBASILICA)) {
if (sd->sc.data[type]) if (sd->sc.getSCE(type))
status_change_end(&sd->bl, type); status_change_end(&sd->bl, type);
} }
else if (!sd->sc.data[type]) else if (!sd->sc.getSCE(type))
sc_start(&sd->bl,&sd->bl, type,100,0,INFINITE_TICK); sc_start(&sd->bl,&sd->bl, type,100,0,INFINITE_TICK);
} }
@ -15235,6 +15235,76 @@ void pc_attendance_claim_reward( struct map_session_data* sd ){
clif_attendence_response( sd, attendance_counter ); clif_attendence_response( sd, attendance_counter );
} }
/**
* Send a player to jail and determine the location to send in jail.
* @param sd: Player data
* @param duration: Duration in minutes (default INT_MAX = infinite)
*/
void pc_jail(map_session_data &sd, int32 duration) {
uint16 m_index = mapindex_name2id(MAP_JAIL);
int16 x, y;
switch (rnd() % 2) { // Jail Locations
case 0: // Jail #1
x = 49;
y = 75;
break;
default: // Default Jail
x = 24;
y = 75;
break;
}
duration = i32max(0, duration); // Can't be less than 0 seconds.
// If duration > 0 then triggered via jailfor which checks every minute.
// If duration == INT_MAX then triggered via jail for infinite duration.
// If duration == 0 then triggered via unjail and end status.
if (duration > 0)
sc_start4(nullptr, &sd.bl, SC_JAILED, 100, duration, m_index, x, y, 60000);
else
status_change_end(&sd.bl, SC_JAILED);
}
/**
* Determine the punishment type when failing macro checks.
* @param sd: Player data
* @param stype: Macro detection status type (for banning)
*/
static void pc_macro_punishment(map_session_data &sd, e_macro_detect_status stype) {
int32 duration = 0;
// Determine if there's a unique duration
if (battle_config.macro_detection_punishment_time > 0) {
char time[13];
safesnprintf(time, 13, "+%dnm", battle_config.macro_detection_punishment_time);
duration = static_cast<int32>(solve_time(time));
}
// Delete the timer
if (sd.macro_detect.timer != INVALID_TIMER)
delete_timer(sd.macro_detect.timer, pc_macro_detector_timeout);
// Clear the macro detect data
sd.macro_detect = {};
sd.macro_detect.timer = INVALID_TIMER;
// Unblock all actions for the player
sd.state.block_action &= ~PCBLOCK_ALL;
sd.state.block_action &= ~PCBLOCK_IMMUNE;
if (battle_config.macro_detection_punishment == 0) { // Ban
clif_macro_detector_status(sd, stype);
chrif_req_login_operation(sd.macro_detect.reporter_aid, sd.status.name, (duration == 0 ? CHRIF_OP_LOGIN_BLOCK : CHRIF_OP_LOGIN_BAN), duration, 0, 0);
} else { // Jail
// Send success to close the window without closing the client
clif_macro_detector_status(sd, MCD_GOOD);
pc_jail(sd, (duration == 0 ? INT_MAX : duration / 60));
}
}
/** /**
* Save a captcha image to memory via /macro_register. * Save a captcha image to memory via /macro_register.
* @param sd: Player data * @param sd: Player data
@ -15320,9 +15390,8 @@ TIMER_FUNC(pc_macro_detector_timeout) {
sd->macro_detect.retry -= 1; sd->macro_detect.retry -= 1;
if (sd->macro_detect.retry == 0) { if (sd->macro_detect.retry == 0) {
// All attempts have been exhausted block the user // All attempts have been exhausted, punish the user
clif_macro_detector_status(*sd, MCD_TIMEOUT); pc_macro_punishment(*sd, MCD_TIMEOUT);
chrif_req_login_operation(sd->macro_detect.reporter_aid, sd->status.name, CHRIF_OP_LOGIN_BLOCK, 0, 0, 0);
} else { } else {
// Update the client // Update the client
clif_macro_detector_request_show(*sd); clif_macro_detector_request_show(*sd);
@ -15373,10 +15442,9 @@ void pc_macro_detector_process_answer(map_session_data &sd, char captcha_answer[
// Deduct an answering attempt // Deduct an answering attempt
sd.macro_detect.retry -= 1; sd.macro_detect.retry -= 1;
// All attempts have been exhausted block the user // All attempts have been exhausted, punish the user
if (sd.macro_detect.retry <= 0) { if (sd.macro_detect.retry <= 0) {
clif_macro_detector_status(sd, MCD_INCORRECT); pc_macro_punishment(sd, MCD_INCORRECT);
chrif_req_login_operation(sd.macro_detect.reporter_aid, sd.status.name, CHRIF_OP_LOGIN_BLOCK, 0, 0, 0);
return; return;
} }
@ -15399,9 +15467,9 @@ void pc_macro_detector_disconnect(map_session_data &sd) {
sd.macro_detect.timer = INVALID_TIMER; sd.macro_detect.timer = INVALID_TIMER;
} }
// If the player disconnects before clearing the challenge the account is banned. // If the player disconnects before clearing the challenge the player is punished.
if (sd.macro_detect.retry != 0) if (sd.macro_detect.retry != 0)
chrif_req_login_operation(sd.macro_detect.reporter_aid, sd.status.name, CHRIF_OP_LOGIN_BLOCK, 0, 0, 0); pc_macro_punishment(sd, MCD_TIMEOUT);
} }
/** /**
@ -15438,10 +15506,10 @@ void pc_macro_reporter_area_select(map_session_data &sd, const int16 x, const in
/** /**
* Send out captcha check to player. * Send out captcha check to player.
* @param ssd: Source player data * @param sd: Target player data
* @param tsd: Target player data * @param reporter_account_id: Account ID of reporter
*/ */
void pc_macro_reporter_process(map_session_data &ssd, map_session_data &tsd) { void pc_macro_reporter_process(map_session_data &sd, int32 reporter_account_id) {
if (captcha_db.empty()) if (captcha_db.empty())
return; return;
@ -15449,18 +15517,18 @@ void pc_macro_reporter_process(map_session_data &ssd, map_session_data &tsd) {
const std::shared_ptr<s_captcha_data> cd = captcha_db.random(); const std::shared_ptr<s_captcha_data> cd = captcha_db.random();
// Set macro detection data. // Set macro detection data.
tsd.macro_detect.cd = cd; sd.macro_detect.cd = cd;
tsd.macro_detect.reporter_aid = ssd.status.account_id; sd.macro_detect.reporter_aid = reporter_account_id;
tsd.macro_detect.retry = battle_config.macro_detection_retry; sd.macro_detect.retry = battle_config.macro_detection_retry;
// Block all actions for the target player. // Block all actions for the target player.
tsd.state.block_action |= (PCBLOCK_ALL | PCBLOCK_IMMUNE); sd.state.block_action |= (PCBLOCK_ALL | PCBLOCK_IMMUNE);
// Open macro detect client side. // Open macro detect client side.
clif_macro_detector_request(tsd); clif_macro_detector_request(sd);
// Start the timeout timer. // Start the timeout timer.
tsd.macro_detect.timer = add_timer(gettick() + battle_config.macro_detection_timeout, pc_macro_detector_timeout, tsd.bl.id, 0); sd.macro_detect.timer = add_timer(gettick() + battle_config.macro_detection_timeout, pc_macro_detector_timeout, sd.bl.id, 0);
} }
/** /**

View File

@ -372,7 +372,8 @@ struct s_qi_display {
e_questinfo_markcolor color; e_questinfo_markcolor color;
}; };
struct map_session_data { class map_session_data {
public:
struct block_list bl; struct block_list bl;
struct unit_data ud; struct unit_data ud;
struct view_data vd; struct view_data vd;
@ -1151,7 +1152,7 @@ static bool pc_cant_act( struct map_session_data* sd ){
#define pc_isvip(sd) ( false ) #define pc_isvip(sd) ( false )
#endif #endif
#ifdef NEW_CARTS #ifdef NEW_CARTS
#define pc_iscarton(sd) ( (sd)->sc.data[SC_PUSH_CART] ) #define pc_iscarton(sd) ( (sd)->sc.getSCE(SC_PUSH_CART) )
#else #else
#define pc_iscarton(sd) ( (sd)->sc.option&OPTION_CART ) #define pc_iscarton(sd) ( (sd)->sc.option&OPTION_CART )
#endif #endif
@ -1232,14 +1233,14 @@ enum e_mado_type : uint16 {
#define pc_rightside_mdef(sd) ( (sd)->battle_status.mdef2 - ((sd)->battle_status.vit>>1) ) #define pc_rightside_mdef(sd) ( (sd)->battle_status.mdef2 - ((sd)->battle_status.vit>>1) )
#define pc_leftside_matk(sd) \ #define pc_leftside_matk(sd) \
(\ (\
((sd)->sc.data[SC_MAGICPOWER] && (sd)->sc.data[SC_MAGICPOWER]->val4) \ ((sd)->sc.getSCE(SC_MAGICPOWER) && (sd)->sc.getSCE(SC_MAGICPOWER)->val4) \
?((sd)->battle_status.matk_min * 100 + 50) / ((sd)->sc.data[SC_MAGICPOWER]->val3+100) \ ?((sd)->battle_status.matk_min * 100 + 50) / ((sd)->sc.getSCE(SC_MAGICPOWER)->val3+100) \
:(sd)->battle_status.matk_min \ :(sd)->battle_status.matk_min \
) )
#define pc_rightside_matk(sd) \ #define pc_rightside_matk(sd) \
(\ (\
((sd)->sc.data[SC_MAGICPOWER] && (sd)->sc.data[SC_MAGICPOWER]->val4) \ ((sd)->sc.getSCE(SC_MAGICPOWER) && (sd)->sc.getSCE(SC_MAGICPOWER)->val4) \
?((sd)->battle_status.matk_max * 100 + 50) / ((sd)->sc.data[SC_MAGICPOWER]->val3+100) \ ?((sd)->battle_status.matk_max * 100 + 50) / ((sd)->sc.getSCE(SC_MAGICPOWER)->val3+100) \
:(sd)->battle_status.matk_max \ :(sd)->battle_status.matk_max \
) )
#endif #endif
@ -1722,17 +1723,20 @@ bool pc_attendance_enabled();
int32 pc_attendance_counter( struct map_session_data* sd ); int32 pc_attendance_counter( struct map_session_data* sd );
void pc_attendance_claim_reward( struct map_session_data* sd ); void pc_attendance_claim_reward( struct map_session_data* sd );
void pc_jail(map_session_data &sd, int32 duration = INT_MAX);
// Captcha Register // Captcha Register
void pc_macro_captcha_register(map_session_data &sd, uint16 image_size, char captcha_answer[CAPTCHA_ANSWER_SIZE]); void pc_macro_captcha_register(map_session_data &sd, uint16 image_size, char captcha_answer[CAPTCHA_ANSWER_SIZE]);
void pc_macro_captcha_register_upload(map_session_data & sd, uint16 upload_size, char *upload_data); void pc_macro_captcha_register_upload(map_session_data & sd, uint16 upload_size, char *upload_data);
// Macro Detector // Macro Detector
TIMER_FUNC(pc_macro_detector_timeout);
void pc_macro_detector_process_answer(map_session_data &sd, char captcha_answer[CAPTCHA_ANSWER_SIZE]); void pc_macro_detector_process_answer(map_session_data &sd, char captcha_answer[CAPTCHA_ANSWER_SIZE]);
void pc_macro_detector_disconnect(map_session_data &sd); void pc_macro_detector_disconnect(map_session_data &sd);
// Macro Reporter // Macro Reporter
void pc_macro_reporter_area_select(map_session_data &sd, const int16 x, const int16 y, const int8 radius); void pc_macro_reporter_area_select(map_session_data &sd, const int16 x, const int16 y, const int8 radius);
void pc_macro_reporter_process(map_session_data &ssd, map_session_data &tsd); void pc_macro_reporter_process(map_session_data &sd, int32 reporter_account_id = -1);
#ifdef MAP_GENERATOR #ifdef MAP_GENERATOR
void pc_reputation_generate(); void pc_reputation_generate();

View File

@ -1295,7 +1295,7 @@ int pet_catch_process2(struct map_session_data* sd, int target_id)
struct status_change* tsc = status_get_sc( &md->bl ); struct status_change* tsc = status_get_sc( &md->bl );
if( battle_config.pet_hide_check && tsc && ( tsc->data[SC_HIDING] || tsc->data[SC_CLOAKING] || tsc->data[SC_CAMOUFLAGE] || tsc->data[SC_NEWMOON] || tsc->data[SC_CLOAKINGEXCEED] ) ){ if( battle_config.pet_hide_check && tsc && ( tsc->getSCE(SC_HIDING) || tsc->getSCE(SC_CLOAKING) || tsc->getSCE(SC_CAMOUFLAGE) || tsc->getSCE(SC_NEWMOON) || tsc->getSCE(SC_CLOAKINGEXCEED) ) ){
clif_pet_roulette( sd, 0 ); clif_pet_roulette( sd, 0 );
sd->catch_target_class = PET_CATCH_FAIL; sd->catch_target_class = PET_CATCH_FAIL;
@ -2066,7 +2066,7 @@ TIMER_FUNC(pet_recovery_timer){
return 0; return 0;
} }
if(sd->sc.data[pd->recovery->type]) { if(sd->sc.getSCE(pd->recovery->type)) {
//Display a heal animation? //Display a heal animation?
//Detoxify is chosen for now. //Detoxify is chosen for now.
clif_skill_nodamage(&pd->bl,&sd->bl,TF_DETOXIFY,1,1); clif_skill_nodamage(&pd->bl,&sd->bl,TF_DETOXIFY,1,1);

View File

@ -6043,16 +6043,16 @@ BUILDIN_FUNC(percentheal)
return SCRIPT_CMD_SUCCESS; return SCRIPT_CMD_SUCCESS;
#ifdef RENEWAL #ifdef RENEWAL
if( sd->sc.data[SC_EXTREMITYFIST2] ) if( sd->sc.getSCE(SC_EXTREMITYFIST2) )
sp = 0; sp = 0;
#endif #endif
if (sd->sc.data[SC_NORECOVER_STATE]) { if (sd->sc.getSCE(SC_NORECOVER_STATE)) {
hp = 0; hp = 0;
sp = 0; sp = 0;
} }
if (sd->sc.data[SC_BITESCAR]) if (sd->sc.getSCE(SC_BITESCAR))
hp = 0; hp = 0;
pc_percentheal(sd,hp,sp); pc_percentheal(sd,hp,sp);
@ -12321,7 +12321,7 @@ BUILDIN_FUNC(sc_end)
if (sc == nullptr) if (sc == nullptr)
return SCRIPT_CMD_SUCCESS; return SCRIPT_CMD_SUCCESS;
struct status_change_entry *sce = sc->data[type]; struct status_change_entry *sce = sc->getSCE(type);
if (sce == nullptr) if (sce == nullptr)
return SCRIPT_CMD_SUCCESS; return SCRIPT_CMD_SUCCESS;
@ -12418,7 +12418,7 @@ BUILDIN_FUNC(getstatus)
return SCRIPT_CMD_SUCCESS; return SCRIPT_CMD_SUCCESS;
} }
if( sd->sc.count == 0 || !sd->sc.data[id] ) if( sd->sc.count == 0 || !sd->sc.getSCE(id) )
{// no status is active {// no status is active
script_pushint(st, 0); script_pushint(st, 0);
return SCRIPT_CMD_SUCCESS; return SCRIPT_CMD_SUCCESS;
@ -12426,13 +12426,13 @@ BUILDIN_FUNC(getstatus)
switch( type ) switch( type )
{ {
case 1: script_pushint(st, sd->sc.data[id]->val1); break; case 1: script_pushint(st, sd->sc.getSCE(id)->val1); break;
case 2: script_pushint(st, sd->sc.data[id]->val2); break; case 2: script_pushint(st, sd->sc.getSCE(id)->val2); break;
case 3: script_pushint(st, sd->sc.data[id]->val3); break; case 3: script_pushint(st, sd->sc.getSCE(id)->val3); break;
case 4: script_pushint(st, sd->sc.data[id]->val4); break; case 4: script_pushint(st, sd->sc.getSCE(id)->val4); break;
case 5: case 5:
{ {
struct TimerData* timer = (struct TimerData*)get_timer(sd->sc.data[id]->timer); struct TimerData* timer = (struct TimerData*)get_timer(sd->sc.getSCE(id)->timer);
if( timer ) if( timer )
{// return the amount of time remaining {// return the amount of time remaining
@ -22395,7 +22395,7 @@ BUILDIN_FUNC(ismounting) {
if (!script_charid2sd(2,sd)) if (!script_charid2sd(2,sd))
return SCRIPT_CMD_FAILURE; return SCRIPT_CMD_FAILURE;
if( sd->sc.data[SC_ALL_RIDING] ) if( sd->sc.getSCE(SC_ALL_RIDING) )
script_pushint(st,1); script_pushint(st,1);
else else
script_pushint(st,0); script_pushint(st,0);
@ -22416,11 +22416,11 @@ BUILDIN_FUNC(setmounting) {
if( sd->sc.option&(OPTION_WUGRIDER|OPTION_RIDING|OPTION_DRAGON|OPTION_MADOGEAR) ) { if( sd->sc.option&(OPTION_WUGRIDER|OPTION_RIDING|OPTION_DRAGON|OPTION_MADOGEAR) ) {
clif_msg(sd, NEED_REINS_OF_MOUNT); clif_msg(sd, NEED_REINS_OF_MOUNT);
script_pushint(st,0); //can't mount with one of these script_pushint(st,0); //can't mount with one of these
} else if (sd->sc.data[SC_CLOAKING] || sd->sc.data[SC_CHASEWALK] || sd->sc.data[SC_CLOAKINGEXCEED] || sd->sc.data[SC_CAMOUFLAGE] || sd->sc.data[SC_STEALTHFIELD] || sd->sc.data[SC__FEINTBOMB]) { } else if (sd->sc.getSCE(SC_CLOAKING) || sd->sc.getSCE(SC_CHASEWALK) || sd->sc.getSCE(SC_CLOAKINGEXCEED) || sd->sc.getSCE(SC_CAMOUFLAGE) || sd->sc.getSCE(SC_STEALTHFIELD) || sd->sc.getSCE(SC__FEINTBOMB)) {
// SC_HIDING, SC__INVISIBILITY, SC__SHADOWFORM, SC_SUHIDE already disable item usage // SC_HIDING, SC__INVISIBILITY, SC__SHADOWFORM, SC_SUHIDE already disable item usage
script_pushint(st, 0); // Silent failure script_pushint(st, 0); // Silent failure
} else { } else {
if( sd->sc.data[SC_ALL_RIDING] ) if( sd->sc.getSCE(SC_ALL_RIDING) )
status_change_end(&sd->bl, SC_ALL_RIDING); //release mount status_change_end(&sd->bl, SC_ALL_RIDING); //release mount
else else
sc_start(NULL, &sd->bl, SC_ALL_RIDING, 10000, 1, INFINITE_TICK); //mount sc_start(NULL, &sd->bl, SC_ALL_RIDING, 10000, 1, INFINITE_TICK); //mount
@ -26829,6 +26829,25 @@ BUILDIN_FUNC(isdead) {
return SCRIPT_CMD_SUCCESS; return SCRIPT_CMD_SUCCESS;
} }
BUILDIN_FUNC(macro_detector) {
map_session_data *sd;
if (script_hasdata(st, 2) && script_isstring(st, 2)) { // Character Name
if (!script_nick2sd(2, sd)) {
return SCRIPT_CMD_FAILURE;
}
} else { // Account ID
if (!script_accid2sd(2, sd)) {
return SCRIPT_CMD_FAILURE;
}
}
// Reporter Account ID as -1 for server.
pc_macro_reporter_process(*sd);
return SCRIPT_CMD_SUCCESS;
}
#include "../custom/script.inc" #include "../custom/script.inc"
// declarations that were supposed to be exported from npc_chat.cpp // declarations that were supposed to be exported from npc_chat.cpp
@ -27582,6 +27601,8 @@ struct script_function buildin_func[] = {
BUILDIN_DEF(getfame, "?"), BUILDIN_DEF(getfame, "?"),
BUILDIN_DEF(getfamerank, "?"), BUILDIN_DEF(getfamerank, "?"),
BUILDIN_DEF(isdead, "?"), BUILDIN_DEF(isdead, "?"),
BUILDIN_DEF(macro_detector, "?"),
#include "../custom/script_def.inc" #include "../custom/script_def.inc"
{NULL,NULL,NULL}, {NULL,NULL,NULL},

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -3134,7 +3134,8 @@ struct status_change_entry {
}; };
///Status change ///Status change
struct status_change { class status_change {
public:
unsigned int option;// effect state (bitfield) unsigned int option;// effect state (bitfield)
unsigned int opt3;// skill state (bitfield) unsigned int opt3;// skill state (bitfield)
unsigned short opt1;// body state unsigned short opt1;// body state
@ -3165,7 +3166,16 @@ struct status_change {
#ifndef RENEWAL #ifndef RENEWAL
unsigned char sg_counter; //Storm gust counter (previous hits from storm gust) unsigned char sg_counter; //Storm gust counter (previous hits from storm gust)
#endif #endif
private:
struct status_change_entry *data[SC_MAX]; struct status_change_entry *data[SC_MAX];
std::pair<enum sc_type, struct status_change_entry *> lastStatus; // last-fetched status
public:
status_change_entry * getSCE(enum sc_type type);
status_change_entry * getSCE(uint32 type);
status_change_entry * createSCE(enum sc_type type);
void deleteSCE(enum sc_type type);
void clearSCE(enum sc_type type);
}; };
int status_damage( struct block_list *src, struct block_list *target, int64 dhp, int64 dsp, int64 dap, t_tick walkdelay, int flag, uint16 skill_id ); int status_damage( struct block_list *src, struct block_list *target, int64 dhp, int64 dsp, int64 dap, t_tick walkdelay, int flag, uint16 skill_id );

View File

@ -769,7 +769,7 @@ int unit_walktoxy( struct block_list *bl, short x, short y, unsigned char flag)
unit_stop_attack(bl); //Sets target to 0 unit_stop_attack(bl); //Sets target to 0
status_change* sc = status_get_sc(bl); status_change* sc = status_get_sc(bl);
if (sc && sc->data[SC_CONFUSION]) // Randomize the target position if (sc && sc->getSCE(SC_CONFUSION)) // Randomize the target position
map_random_dir(bl, &ud->to_x, &ud->to_y); map_random_dir(bl, &ud->to_x, &ud->to_y);
if(ud->walktimer != INVALID_TIMER) { if(ud->walktimer != INVALID_TIMER) {
@ -879,7 +879,7 @@ int unit_walktobl(struct block_list *bl, struct block_list *tbl, int range, unsi
unit_stop_attack(bl); //Sets target to 0 unit_stop_attack(bl); //Sets target to 0
status_change *sc = status_get_sc(bl); status_change *sc = status_get_sc(bl);
if (sc && sc->data[SC_CONFUSION]) // Randomize the target position if (sc && sc->getSCE(SC_CONFUSION)) // Randomize the target position
map_random_dir(bl, &ud->to_x, &ud->to_y); map_random_dir(bl, &ud->to_x, &ud->to_y);
if(ud->walktimer != INVALID_TIMER) { if(ud->walktimer != INVALID_TIMER) {
@ -912,7 +912,7 @@ int unit_walktobl(struct block_list *bl, struct block_list *tbl, int range, unsi
*/ */
void unit_run_hit(struct block_list *bl, struct status_change *sc, struct map_session_data *sd, enum sc_type type) void unit_run_hit(struct block_list *bl, struct status_change *sc, struct map_session_data *sd, enum sc_type type)
{ {
int lv = sc->data[type]->val1; int lv = sc->getSCE(type)->val1;
// If you can't run forward, you must be next to a wall, so bounce back. [Skotlex] // If you can't run forward, you must be next to a wall, so bounce back. [Skotlex]
if (type == SC_RUN) if (type == SC_RUN)
@ -948,7 +948,7 @@ bool unit_run(struct block_list *bl, struct map_session_data *sd, enum sc_type t
sc = status_get_sc(bl); sc = status_get_sc(bl);
if (!(sc && sc->data[type])) if (!(sc && sc->getSCE(type)))
return false; return false;
if (!unit_can_move(bl)) { if (!unit_can_move(bl)) {
@ -956,8 +956,8 @@ bool unit_run(struct block_list *bl, struct map_session_data *sd, enum sc_type t
return false; return false;
} }
dir_x = dirx[sc->data[type]->val2]; dir_x = dirx[sc->getSCE(type)->val2];
dir_y = diry[sc->data[type]->val2]; dir_y = diry[sc->getSCE(type)->val2];
// Determine destination cell // Determine destination cell
to_x = bl->x; to_x = bl->x;
@ -1252,7 +1252,7 @@ enum e_unit_blown unit_blown_immune(struct block_list* bl, uint8 flag)
#ifndef RENEWAL #ifndef RENEWAL
// Basilica caster can't be knocked-back by normal monsters. // Basilica caster can't be knocked-back by normal monsters.
if( !(flag&0x4) && sd->sc.data[SC_BASILICA] && sd->sc.data[SC_BASILICA]->val4 == sd->bl.id) if( !(flag&0x4) && sd->sc.getSCE(SC_BASILICA) && sd->sc.getSCE(SC_BASILICA)->val4 == sd->bl.id)
return UB_TARGET_BASILICA; return UB_TARGET_BASILICA;
#endif #endif
// Target has special_state.no_knockback (equip) // Target has special_state.no_knockback (equip)
@ -1638,14 +1638,14 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
return 0; return 0;
// temp: used to signal combo-skills right now. // temp: used to signal combo-skills right now.
if (sc && sc->data[SC_COMBO] && if (sc && sc->getSCE(SC_COMBO) &&
skill_is_combo(skill_id) && skill_is_combo(skill_id) &&
(sc->data[SC_COMBO]->val1 == skill_id || (sc->getSCE(SC_COMBO)->val1 == skill_id ||
(sd?skill_check_condition_castbegin(sd,skill_id,skill_lv):0) )) { (sd?skill_check_condition_castbegin(sd,skill_id,skill_lv):0) )) {
if (skill_is_combo(skill_id) == 2 && target_id == src->id && ud->target > 0) if (skill_is_combo(skill_id) == 2 && target_id == src->id && ud->target > 0)
target_id = ud->target; target_id = ud->target;
else if (sc->data[SC_COMBO]->val2) else if (sc->getSCE(SC_COMBO)->val2)
target_id = sc->data[SC_COMBO]->val2; target_id = sc->getSCE(SC_COMBO)->val2;
else if (target_id == src->id || ud->target > 0) else if (target_id == src->id || ud->target > 0)
target_id = ud->target; target_id = ud->target;
@ -1665,21 +1665,21 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
switch(skill_id) { // Check for skills that auto-select target switch(skill_id) { // Check for skills that auto-select target
case MO_CHAINCOMBO: case MO_CHAINCOMBO:
if (sc && sc->data[SC_BLADESTOP]) { if (sc && sc->getSCE(SC_BLADESTOP)) {
if ((target=map_id2bl(sc->data[SC_BLADESTOP]->val4)) == NULL) if ((target=map_id2bl(sc->getSCE(SC_BLADESTOP)->val4)) == NULL)
return 0; return 0;
} }
break; break;
case GC_WEAPONCRUSH: case GC_WEAPONCRUSH:
if (sc && sc->data[SC_WEAPONBLOCK_ON]) { if (sc && sc->getSCE(SC_WEAPONBLOCK_ON)) {
if ((target = map_id2bl(sc->data[SC_WEAPONBLOCK_ON]->val1)) == nullptr) if ((target = map_id2bl(sc->getSCE(SC_WEAPONBLOCK_ON)->val1)) == nullptr)
return 0; return 0;
combo = 1; combo = 1;
} }
break; break;
case RL_QD_SHOT: case RL_QD_SHOT:
if (sc && sc->data[SC_QD_SHOT_READY]) { if (sc && sc->getSCE(SC_QD_SHOT_READY)) {
if ((target = map_id2bl(sc->data[SC_QD_SHOT_READY]->val1)) == nullptr) if ((target = map_id2bl(sc->getSCE(SC_QD_SHOT_READY)->val1)) == nullptr)
return 0; return 0;
combo = 1; combo = 1;
} }
@ -1717,8 +1717,8 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
case MH_TINDER_BREAKER: { case MH_TINDER_BREAKER: {
int skill_id2 = ((skill_id==MH_SONIC_CRAW)?MH_MIDNIGHT_FRENZY:MH_EQC); int skill_id2 = ((skill_id==MH_SONIC_CRAW)?MH_MIDNIGHT_FRENZY:MH_EQC);
if(sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == skill_id2) { // It's a combo if(sc->getSCE(SC_COMBO) && sc->getSCE(SC_COMBO)->val1 == skill_id2) { // It's a combo
target_id = sc->data[SC_COMBO]->val2; target_id = sc->getSCE(SC_COMBO)->val2;
combo = 1; combo = 1;
casttime = -1; casttime = -1;
} }
@ -1907,17 +1907,17 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
casttime += casttime * min(skill_lv, sd->spiritball); casttime += casttime * min(skill_lv, sd->spiritball);
break; break;
case MO_EXTREMITYFIST: case MO_EXTREMITYFIST:
if (sc && sc->data[SC_COMBO] && if (sc && sc->getSCE(SC_COMBO) &&
(sc->data[SC_COMBO]->val1 == MO_COMBOFINISH || (sc->getSCE(SC_COMBO)->val1 == MO_COMBOFINISH ||
sc->data[SC_COMBO]->val1 == CH_TIGERFIST || sc->getSCE(SC_COMBO)->val1 == CH_TIGERFIST ||
sc->data[SC_COMBO]->val1 == CH_CHAINCRUSH)) sc->getSCE(SC_COMBO)->val1 == CH_CHAINCRUSH))
casttime = -1; casttime = -1;
combo = 1; combo = 1;
break; break;
case SR_GATEOFHELL: case SR_GATEOFHELL:
case SR_TIGERCANNON: case SR_TIGERCANNON:
if (sc && sc->data[SC_COMBO] && if (sc && sc->getSCE(SC_COMBO) &&
sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE) sc->getSCE(SC_COMBO)->val1 == SR_FALLENEMPIRE)
casttime = -1; casttime = -1;
combo = 1; combo = 1;
break; break;
@ -1926,17 +1926,17 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
break; break;
#ifndef RENEWAL_CAST #ifndef RENEWAL_CAST
case ST_CHASEWALK: case ST_CHASEWALK:
if (sc && sc->data[SC_CHASEWALK]) if (sc && sc->getSCE(SC_CHASEWALK))
casttime = -1; casttime = -1;
break; break;
#endif #endif
case TK_RUN: case TK_RUN:
if (sc && sc->data[SC_RUN]) if (sc && sc->getSCE(SC_RUN))
casttime = -1; casttime = -1;
break; break;
#ifndef RENEWAL #ifndef RENEWAL
case HP_BASILICA: case HP_BASILICA:
if( sc && sc->data[SC_BASILICA] ) if( sc && sc->getSCE(SC_BASILICA) )
casttime = -1; // No Casting time on basilica cancel casttime = -1; // No Casting time on basilica cancel
break; break;
#endif #endif
@ -1955,14 +1955,14 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
casttime *= 2; casttime *= 2;
break; break;
case RA_WUGDASH: case RA_WUGDASH:
if (sc && sc->data[SC_WUGDASH]) if (sc && sc->getSCE(SC_WUGDASH))
casttime = -1; casttime = -1;
break; break;
case DK_SERVANT_W_PHANTOM: { // Stops servants from being consumed on unmarked targets. case DK_SERVANT_W_PHANTOM: { // Stops servants from being consumed on unmarked targets.
status_change *tsc = status_get_sc(target); status_change *tsc = status_get_sc(target);
// Only allow to attack if the enemy has a sign mark given by the caster. // Only allow to attack if the enemy has a sign mark given by the caster.
if( tsc == nullptr || tsc->data[SC_SERVANT_SIGN] == nullptr || tsc->data[SC_SERVANT_SIGN]->val1 != src->id ){ if( tsc == nullptr || tsc->getSCE(SC_SERVANT_SIGN) == nullptr || tsc->getSCE(SC_SERVANT_SIGN)->val1 != src->id ){
clif_skill_fail(sd, skill_id, USESKILL_FAIL, 0); clif_skill_fail(sd, skill_id, USESKILL_FAIL, 0);
return 0; return 0;
} }
@ -2056,17 +2056,17 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
if( sc ) { if( sc ) {
// These 3 status do not stack, so it's efficient to use if-else // These 3 status do not stack, so it's efficient to use if-else
if( sc->data[SC_CLOAKING] && !(sc->data[SC_CLOAKING]->val4&4) && skill_id != AS_CLOAKING && skill_id != SHC_SHADOW_STAB) { if( sc->getSCE(SC_CLOAKING) && !(sc->getSCE(SC_CLOAKING)->val4&4) && skill_id != AS_CLOAKING && skill_id != SHC_SHADOW_STAB) {
status_change_end(src, SC_CLOAKING); status_change_end(src, SC_CLOAKING);
if (!src->prev) if (!src->prev)
return 0; // Warped away! return 0; // Warped away!
} else if( sc->data[SC_CLOAKINGEXCEED] && !(sc->data[SC_CLOAKINGEXCEED]->val4&4) && skill_id != GC_CLOAKINGEXCEED && skill_id != SHC_SHADOW_STAB) { } else if( sc->getSCE(SC_CLOAKINGEXCEED) && !(sc->getSCE(SC_CLOAKINGEXCEED)->val4&4) && skill_id != GC_CLOAKINGEXCEED && skill_id != SHC_SHADOW_STAB) {
status_change_end(src,SC_CLOAKINGEXCEED); status_change_end(src,SC_CLOAKINGEXCEED);
if (!src->prev) if (!src->prev)
return 0; return 0;
} else if (sc->data[SC_NEWMOON] && skill_id != SJ_NEWMOONKICK) { } else if (sc->getSCE(SC_NEWMOON) && skill_id != SJ_NEWMOONKICK) {
status_change_end(src, SC_NEWMOON); status_change_end(src, SC_NEWMOON);
if (!src->prev) if (!src->prev)
return 0; // Warped away! return 0; // Warped away!
@ -2238,17 +2238,17 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui
if( sc ) { if( sc ) {
// These 3 status do not stack, so it's efficient to use if-else // These 3 status do not stack, so it's efficient to use if-else
if (sc->data[SC_CLOAKING] && !(sc->data[SC_CLOAKING]->val4&4)) { if (sc->getSCE(SC_CLOAKING) && !(sc->getSCE(SC_CLOAKING)->val4&4)) {
status_change_end(src, SC_CLOAKING); status_change_end(src, SC_CLOAKING);
if (!src->prev) if (!src->prev)
return 0; // Warped away! return 0; // Warped away!
} else if (sc->data[SC_CLOAKINGEXCEED] && !(sc->data[SC_CLOAKINGEXCEED]->val4&4)) { } else if (sc->getSCE(SC_CLOAKINGEXCEED) && !(sc->getSCE(SC_CLOAKINGEXCEED)->val4&4)) {
status_change_end(src, SC_CLOAKINGEXCEED); status_change_end(src, SC_CLOAKINGEXCEED);
if (!src->prev) if (!src->prev)
return 0; return 0;
} else if (sc->data[SC_NEWMOON]) { } else if (sc->getSCE(SC_NEWMOON)) {
status_change_end(src, SC_NEWMOON); status_change_end(src, SC_NEWMOON);
if (!src->prev) if (!src->prev)
@ -2871,7 +2871,7 @@ bool unit_can_attack(struct block_list *bl, int target_id) {
if (!(sc = status_get_sc(bl))) if (!(sc = status_get_sc(bl)))
return true; return true;
if (sc->cant.attack || (sc->data[SC_VOICEOFSIREN] && sc->data[SC_VOICEOFSIREN]->val2 == target_id)) if (sc->cant.attack || (sc->getSCE(SC_VOICEOFSIREN) && sc->getSCE(SC_VOICEOFSIREN)->val2 == target_id))
return false; return false;
return true; return true;
@ -2904,7 +2904,7 @@ int unit_skillcastcancel(struct block_list *bl, char type)
return 0; return 0;
if (sd && (sd->special_state.no_castcancel2 || if (sd && (sd->special_state.no_castcancel2 ||
((sd->sc.data[SC_UNLIMITEDHUMMINGVOICE] || sd->special_state.no_castcancel) && !map_flag_gvg2(bl->m) && !map_getmapflag(bl->m, MF_BATTLEGROUND)))) // fixed flags being read the wrong way around [blackhole89] ((sd->sc.getSCE(SC_UNLIMITEDHUMMINGVOICE) || sd->special_state.no_castcancel) && !map_flag_gvg2(bl->m) && !map_getmapflag(bl->m, MF_BATTLEGROUND)))) // fixed flags being read the wrong way around [blackhole89]
return 0; return 0;
} }
@ -3076,9 +3076,9 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file,
status_change_end(bl, SC_CLOAKING); status_change_end(bl, SC_CLOAKING);
status_change_end(bl, SC_CLOAKINGEXCEED); status_change_end(bl, SC_CLOAKINGEXCEED);
} }
if (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF) if (sc->getSCE(SC_GOSPEL) && sc->getSCE(SC_GOSPEL)->val4 == BCT_SELF)
status_change_end(bl, SC_GOSPEL); status_change_end(bl, SC_GOSPEL);
if (sc->data[SC_PROVOKE] && sc->data[SC_PROVOKE]->val4 == 1) if (sc->getSCE(SC_PROVOKE) && sc->getSCE(SC_PROVOKE)->val4 == 1)
status_change_end(bl, SC_PROVOKE); //End infinite provoke to prevent exploit status_change_end(bl, SC_PROVOKE); //End infinite provoke to prevent exploit
} }
@ -3691,8 +3691,8 @@ void unit_addshadowscar(unit_data &ud, int interval) {
status_change *sc = status_get_sc(ud.bl); status_change *sc = status_get_sc(ud.bl);
if (sc != nullptr) { if (sc != nullptr) {
if (sc->data[SC_SHADOW_SCAR] != nullptr) { if (sc->getSCE(SC_SHADOW_SCAR) != nullptr) {
sc->data[SC_SHADOW_SCAR]->val1 = static_cast<int>(ud.shadow_scar_timer.size()); sc->getSCE(SC_SHADOW_SCAR)->val1 = static_cast<int>(ud.shadow_scar_timer.size());
} else { } else {
sc_start(ud.bl, ud.bl, SC_SHADOW_SCAR, 100, 1, INFINITE_TICK); sc_start(ud.bl, ud.bl, SC_SHADOW_SCAR, 100, 1, INFINITE_TICK);
} }