Initial implementation of the goldpc timer
Fixes #6912 Thanks to @Balferian
This commit is contained in:
parent
a763ad0629
commit
4b16e4b020
@ -135,3 +135,19 @@ feature.dynamicnpc_rangey: 2
|
||||
// Should the dynamic NPCs look into the direction of the player? (Note 1)
|
||||
// Default: no
|
||||
feature.dynamicnpc_direction: no
|
||||
|
||||
// Enable the Gold PC timer? (Note 1)
|
||||
// Default: yes
|
||||
feature.goldpc_active: yes
|
||||
|
||||
// How many seconds does a player have to be online to receive a point?
|
||||
// Default: 3600s (1h)
|
||||
feature.goldpc_time: 3600
|
||||
|
||||
// How many points can a player have at maximum?
|
||||
// Default: 300
|
||||
feature.goldpc_max_points: 300
|
||||
|
||||
// Should being a VIP player double the points a player gets? (Note 1)
|
||||
// Default: yes
|
||||
feature.goldpc_vip: yes
|
||||
|
12
npc/other/goldpc.txt
Normal file
12
npc/other/goldpc.txt
Normal file
@ -0,0 +1,12 @@
|
||||
//===== rAthena Script =======================================
|
||||
//= Gold PC Bonus NPC
|
||||
//===== Description: =========================================
|
||||
//= NPC that can be spawned via the Gold PC Timer Button.
|
||||
//===== Changelog: ===========================================
|
||||
//= 1.0 Initial release [Lemongrass]
|
||||
//============================================================
|
||||
|
||||
prontera,0,0,5 script Goldpoint Manager::GOLDPCCAFE 4_F_02,{
|
||||
// TODO: Implement
|
||||
end;
|
||||
}
|
@ -179,6 +179,7 @@ npc: npc/other/comodo_gambling.txt
|
||||
npc: npc/other/divorce.txt
|
||||
npc: npc/other/fortune.txt
|
||||
npc: npc/other/gm_npcs.txt
|
||||
npc: npc/other/goldpc.txt
|
||||
npc: npc/other/guildpvp.txt
|
||||
npc: npc/other/gympass.txt
|
||||
npc: npc/other/hugel_bingo.txt
|
||||
|
@ -10276,6 +10276,11 @@ static const struct _battle_data {
|
||||
{ "feature.dynamicnpc_rangey", &battle_config.feature_dynamicnpc_rangey, 2, 0, INT_MAX, },
|
||||
{ "feature.dynamicnpc_direction", &battle_config.feature_dynamicnpc_direction, 0, 0, 1, },
|
||||
|
||||
{ "feature.goldpc_active", &battle_config.feature_goldpc_active, 1, 0, 1, },
|
||||
{ "feature.goldpc_time", &battle_config.feature_goldpc_time, 3600, 0, 3600, },
|
||||
{ "feature.goldpc_max_points", &battle_config.feature_goldpc_max_points, 300, 0, 300, },
|
||||
{ "feature.goldpc_vip", &battle_config.feature_goldpc_vip, 1, 0, 1, },
|
||||
|
||||
#include "../custom/battle_config_init.inc"
|
||||
};
|
||||
|
||||
|
@ -719,6 +719,11 @@ struct Battle_Config
|
||||
int feature_dynamicnpc_rangey;
|
||||
int feature_dynamicnpc_direction;
|
||||
|
||||
int feature_goldpc_active;
|
||||
int feature_goldpc_time;
|
||||
int feature_goldpc_max_points;
|
||||
int feature_goldpc_vip;
|
||||
|
||||
#include "../custom/battle_config_struct.inc"
|
||||
};
|
||||
|
||||
|
@ -324,9 +324,25 @@ int chrif_save(struct map_session_data *sd, int flag) {
|
||||
if (sd->premiumStorage.dirty)
|
||||
storage_premiumStorage_save(sd);
|
||||
|
||||
if (flag&CSAVE_QUITTING)
|
||||
if( flag&CSAVE_QUITTING ){
|
||||
sd->state.storage_flag = 0; //Force close it.
|
||||
|
||||
if( sd->goldpc_tid != INVALID_TIMER ){
|
||||
const struct TimerData* td = get_timer( sd->goldpc_tid );
|
||||
|
||||
if( td != nullptr ){
|
||||
// Get the remaining milliseconds until the next reward
|
||||
t_tick remaining = td->tick - gettick();
|
||||
|
||||
// Always round up to full second and a little safety delay
|
||||
remaining += ( remaining % 1000 ) + 2000;
|
||||
|
||||
// Store the seconds that already fully passed
|
||||
pc_setreg2( sd, GOLDPC_SECONDS_VAR, battle_config.feature_goldpc_time - remaining / 1000 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Saving of registry values.
|
||||
if (sd->vars_dirty)
|
||||
intif_saveregistry(sd);
|
||||
|
@ -24901,6 +24901,50 @@ void clif_macro_reporter_status(map_session_data &sd, e_macro_report_status styp
|
||||
#endif
|
||||
}
|
||||
|
||||
void clif_goldpc_info( struct map_session_data& sd ){
|
||||
#if PACKETVER_MAIN_NUM >= 20140508 || PACKETVER_RE_NUM >= 20140508 || defined(PACKETVER_ZERO)
|
||||
if( battle_config.feature_goldpc_active ){
|
||||
struct PACKET_ZC_GOLDPCCAFE_POINT p = {};
|
||||
|
||||
p.packetType = HEADER_ZC_GOLDPCCAFE_POINT;
|
||||
p.active = sd.goldpc_tid != INVALID_TIMER;
|
||||
if( battle_config.feature_goldpc_vip && pc_isvip( &sd ) ){
|
||||
p.unitPoint = 2;
|
||||
}else{
|
||||
p.unitPoint = 1;
|
||||
}
|
||||
p.point = (int32)pc_readreg2( &sd, GOLDPC_POINT_VAR );
|
||||
// TODO: check if we should send max value, if disabled/max reached
|
||||
p.accumulatePlaySecond = (int32)( 3600 - battle_config.feature_goldpc_time + pc_readreg2( &sd, GOLDPC_SECONDS_VAR ) );
|
||||
|
||||
clif_send( &p, sizeof( p ), &sd.bl, SELF );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void clif_parse_dynamic_npc( int fd, struct map_session_data* sd ){
|
||||
#if PACKETVER_MAIN_NUM >= 20140430 || PACKETVER_RE_NUM >= 20140430 || defined(PACKETVER_ZERO)
|
||||
struct PACKET_CZ_DYNAMICNPC_CREATE_REQUEST* p = (struct PACKET_CZ_DYNAMICNPC_CREATE_REQUEST*)RFIFOP( fd, 0 );
|
||||
|
||||
char npcname[NPC_NAME_LENGTH + 1];
|
||||
|
||||
if( strncasecmp( "GOLDPCCAFE", p->nickname, sizeof( p->nickname ) ) == 0 ){
|
||||
safestrncpy( npcname, p->nickname, sizeof( npcname ) );
|
||||
}else{
|
||||
return;
|
||||
}
|
||||
|
||||
struct npc_data* nd = npc_name2id( npcname );
|
||||
|
||||
if( nd == nullptr ){
|
||||
ShowError( "clif_parse_dynamic_npc: Original NPC \"%s\" was not found.\n", npcname );
|
||||
return;
|
||||
}
|
||||
|
||||
npc_duplicate_npc_for_player( *nd, *sd );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* Main client packet processing function
|
||||
*------------------------------------------*/
|
||||
|
@ -1243,4 +1243,6 @@ void clif_macro_detector_status(map_session_data &sd, e_macro_detect_status styp
|
||||
void clif_macro_reporter_select(map_session_data &sd, const std::vector<uint32> &aid_list);
|
||||
void clif_macro_reporter_status(map_session_data &sd, e_macro_report_status stype);
|
||||
|
||||
void clif_goldpc_info( struct map_session_data& sd );
|
||||
|
||||
#endif /* CLIF_HPP */
|
||||
|
@ -2136,6 +2136,10 @@
|
||||
packet(0x09DA,-1);
|
||||
#endif
|
||||
|
||||
#if PACKETVER_MAIN_NUM >= 20140430 || PACKETVER_RE_NUM >= 20140430 || defined(PACKETVER_ZERO)
|
||||
parseable_packet( HEADER_CZ_DYNAMICNPC_CREATE_REQUEST, sizeof( PACKET_CZ_DYNAMICNPC_CREATE_REQUEST ), clif_parse_dynamic_npc, 0 );
|
||||
#endif
|
||||
|
||||
// 2014-10-08Ragexe
|
||||
#if PACKETVER >= 20141008
|
||||
parseable_packet(0x9FB, -1, clif_parse_pet_evolution, 2, 4); // CZ_PET_EVOLUTION
|
||||
|
@ -367,6 +367,23 @@ struct PACKET_CZ_REQ_CHANGE_MEMBERPOS{
|
||||
struct PACKET_CZ_REQ_CHANGE_MEMBERPOS_sub list[];
|
||||
} __attribute__((packed));
|
||||
|
||||
#if PACKETVER_MAIN_NUM >= 20140508 || PACKETVER_RE_NUM >= 20140508 || defined(PACKETVER_ZERO)
|
||||
struct PACKET_ZC_GOLDPCCAFE_POINT{
|
||||
int16 packetType;
|
||||
int8 active;
|
||||
int8 unitPoint;
|
||||
int32 point;
|
||||
int32 accumulatePlaySecond;
|
||||
} __attribute__((packed));
|
||||
#elif PACKETVER_MAIN_NUM >= 20140430 || PACKETVER_RE_NUM >= 20140430
|
||||
// TODO: find difference (1byte) priority low...
|
||||
#endif
|
||||
|
||||
struct PACKET_CZ_DYNAMICNPC_CREATE_REQUEST{
|
||||
int16 packetType;
|
||||
char nickname[NAME_LENGTH];
|
||||
} __attribute__((packed));
|
||||
|
||||
// NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
|
||||
#if !defined( sun ) && ( !defined( __NETBSD__ ) || __NetBSD_Version__ >= 600000000 )
|
||||
#pragma pack( pop )
|
||||
@ -409,6 +426,8 @@ DEFINE_PACKET_HEADER(ZC_NOTIFY_BARGAIN_SALE_SELLING, 0x9b2)
|
||||
DEFINE_PACKET_HEADER(ZC_NOTIFY_BARGAIN_SALE_CLOSE, 0x9b3)
|
||||
DEFINE_PACKET_HEADER(ZC_ACK_COUNT_BARGAIN_SALE_ITEM, 0x9c4)
|
||||
DEFINE_PACKET_HEADER(ZC_ACK_GUILDSTORAGE_LOG, 0x9da)
|
||||
DEFINE_PACKET_HEADER(ZC_GOLDPCCAFE_POINT, 0xa15)
|
||||
DEFINE_PACKET_HEADER(CZ_DYNAMICNPC_CREATE_REQUEST, 0xa16)
|
||||
DEFINE_PACKET_HEADER(CZ_REQ_APPLY_BARGAIN_SALE_ITEM2, 0xa3d)
|
||||
DEFINE_PACKET_HEADER(CZ_REQ_STYLE_CHANGE, 0xa46)
|
||||
DEFINE_PACKET_HEADER(ZC_STYLE_CHANGE_RES, 0xa47)
|
||||
|
@ -1972,6 +1972,47 @@ bool pc_set_hate_mob(struct map_session_data *sd, int pos, struct block_list *bl
|
||||
return true;
|
||||
}
|
||||
|
||||
TIMER_FUNC(pc_goldpc_update){
|
||||
struct map_session_data* sd = map_id2sd( id );
|
||||
|
||||
if( sd == nullptr ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
sd->goldpc_tid = INVALID_TIMER;
|
||||
|
||||
// Check if feature is still active
|
||||
if( !battle_config.feature_goldpc_active ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO: add mapflag to disable?
|
||||
|
||||
int32 points = (int32)pc_readreg2( sd, GOLDPC_POINT_VAR );
|
||||
|
||||
if( points < battle_config.feature_goldpc_max_points ){
|
||||
if( battle_config.feature_goldpc_vip && pc_isvip( sd ) ){
|
||||
points += 2;
|
||||
}else{
|
||||
points += 1;
|
||||
}
|
||||
|
||||
points = std::min( points, battle_config.feature_goldpc_max_points );
|
||||
|
||||
pc_setreg2( sd, GOLDPC_POINT_VAR, points );
|
||||
pc_setreg2( sd, GOLDPC_SECONDS_VAR, 0 );
|
||||
|
||||
if( points < battle_config.feature_goldpc_max_points ){
|
||||
sd->goldpc_tid = add_timer( gettick() + battle_config.feature_goldpc_time * 1000, pc_goldpc_update, sd->bl.id, NULL );
|
||||
}
|
||||
|
||||
// Update the client
|
||||
clif_goldpc_info( *sd );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* Invoked once after the char/account/account2 registry variables are received. [Skotlex]
|
||||
* We didn't receive item information at this point so DO NOT attempt to do item operations here.
|
||||
@ -2080,6 +2121,13 @@ void pc_reg_received(struct map_session_data *sd)
|
||||
clif_instance_info( *sd );
|
||||
#endif
|
||||
|
||||
if( battle_config.feature_goldpc_active ){
|
||||
sd->goldpc_tid = add_timer( gettick() + ( battle_config.feature_goldpc_time - pc_readreg2( sd, GOLDPC_SECONDS_VAR ) ) * 1000, pc_goldpc_update, sd->bl.id, NULL );
|
||||
clif_goldpc_info( *sd );
|
||||
}else{
|
||||
sd->goldpc_tid = INVALID_TIMER;
|
||||
}
|
||||
|
||||
// pet
|
||||
if (sd->status.pet_id > 0)
|
||||
intif_request_petdata(sd->status.account_id, sd->status.char_id, sd->status.pet_id);
|
||||
@ -15452,6 +15500,7 @@ void do_init_pc(void) {
|
||||
add_timer_func_list(pc_autotrade_timer, "pc_autotrade_timer");
|
||||
add_timer_func_list(pc_on_expire_active, "pc_on_expire_active");
|
||||
add_timer_func_list(pc_macro_detector_timeout, "pc_macro_detector_timeout");
|
||||
add_timer_func_list( pc_goldpc_update, "pc_goldpc_update" );
|
||||
|
||||
add_timer(gettick() + autosave_interval, pc_autosave, 0, 0);
|
||||
|
||||
|
@ -63,6 +63,8 @@ enum sc_type : int16;
|
||||
#define ATTENDANCE_DATE_VAR "#AttendanceDate"
|
||||
#define ATTENDANCE_COUNT_VAR "#AttendanceCounter"
|
||||
#define ACHIEVEMENTLEVEL "AchievementLevel"
|
||||
#define GOLDPC_POINT_VAR "Goldpc_Points"
|
||||
#define GOLDPC_SECONDS_VAR "Goldpc_Seconds"
|
||||
|
||||
//Total number of classes (for data storage)
|
||||
#define CLASS_COUNT (JOB_MAX - JOB_NOVICE_HIGH + JOB_MAX_BASIC)
|
||||
@ -931,6 +933,8 @@ struct map_session_data {
|
||||
} captcha_upload;
|
||||
|
||||
s_macro_detect macro_detect;
|
||||
|
||||
int goldpc_tid;
|
||||
};
|
||||
|
||||
extern struct eri *pc_sc_display_ers; /// Player's SC display table
|
||||
|
Loading…
x
Reference in New Issue
Block a user