Compare commits

...

30 Commits

Author SHA1 Message Date
Aleos
e0af6063dc
Merge branch 'master' into hotfix/issue6912 2024-04-08 12:20:16 -04:00
Lemongrass3110
718458e2ea Merge branch 'master' into hotfix/issue6912
# Conflicts:
#	src/map/clif.cpp
2023-12-29 11:36:22 +01:00
Lemongrass3110
dc7ef60ec9
Apply suggestions from code review
Co-authored-by: Pokye <98105181+Pokye@users.noreply.github.com>
2023-12-29 11:26:09 +01:00
Lemongrass3110
9d8e7f47d7
Apply suggestions from code review
Co-authored-by: Pokye <98105181+Pokye@users.noreply.github.com>
2023-12-29 11:25:29 +01:00
Lemongrass3110
91ecd7bdc8 Merge branch 'master' into hotfix/issue6912
# Conflicts:
#	conf/battle/feature.conf
#	src/map/battle.cpp
#	src/map/battle.hpp
#	src/map/clif.cpp
#	src/map/packets.hpp
#	src/map/pc.hpp
2023-07-19 15:09:30 +02:00
Lemongrass3110
de35836a42 Added some official responses 2022-12-20 18:30:43 +01:00
Lemongrass3110
07c9c6d5ad Removed struct - it is a class now 2022-12-20 18:28:07 +01:00
Lemongrass3110
0ce73b3d5d Merge branch 'master' into hotfix/issue6912
# Conflicts:
#	conf/battle/feature.conf
#	src/map/battle.cpp
#	src/map/battle.hpp
#	src/map/clif.cpp
#	src/map/clif.hpp
#	src/map/packets.hpp
2022-12-20 18:24:47 +01:00
Lemongrass3110
08ed030ade Added some checks if the variable name was already defined 2022-12-13 00:00:03 +01:00
Lemongrass3110
c88afa1c7a Added replay version of buff NPC by @eppc0330 2022-12-01 00:34:46 +01:00
Lemongrass3110
2857e51abd Cleanup of NPC logic 2022-12-01 00:28:38 +01:00
Lemongrass3110
0da07fff32 Translation of the replay 2022-12-01 00:17:02 +01:00
Lemongrass3110
aaa6db65d5 Replay version by @eppc0330 2022-11-30 23:54:35 +01:00
Lemongrass3110
cc76262081 Fixed client getting out of sync 2022-11-30 23:42:13 +01:00
Lemongrass3110
34d0746df6 Fixed some circles during loading 2022-11-30 23:41:52 +01:00
Lemongrass3110
0e4bc36d6b No points for autotraders! 2022-11-30 23:02:41 +01:00
Lemongrass3110
45c799acc9 Added client maximum seconds constant 2022-11-30 23:01:07 +01:00
Lemongrass3110
3353de0e8f Fixed accumulated seconds calculation 2022-11-30 23:00:32 +01:00
Lemongrass3110
b97987e4e7 Changed gold points to parameters 2022-11-30 22:48:40 +01:00
Lemongrass3110
c28886ee0e Overwrite real invalid timer ids 2022-11-30 22:47:35 +01:00
Lemongrass3110
39367c75f5 Merge branch 'master' into hotfix/issue6912
# Conflicts:
#	src/map/packets.hpp
#	src/map/pc.hpp
2022-11-30 22:17:09 +01:00
Lemongrass3110
70b54081da Merge branch 'master' into hotfix/issue6912
# Conflicts:
#	conf/battle/feature.conf
#	src/map/packets.hpp
2022-11-20 19:10:31 +01:00
Lemongrass3110
4f98d0198f Always stop the timer on logout
Thanks to @Tolimatoi
2022-11-20 18:53:44 +01:00
Lemongrass3110
95941df818 No points for autotraders!
Thanks to @secretdataz
2022-11-08 00:22:03 +01:00
Lemongrass3110
cc7215a496 Only start the timer if you have not reached the maximum already 2022-11-07 23:55:22 +01:00
Lemongrass3110
084c0ded15 Fixed some warnings 2022-11-07 23:32:05 +01:00
Lemongrass3110
63cb80aa89
Apply suggestions from code review
Co-authored-by: Aleos <aleos89@users.noreply.github.com>
2022-11-07 19:10:36 +01:00
Lemongrass3110
8053e36190 Fixed VIP display directly after login
Thanks to @ecdarreola
2022-11-07 19:09:31 +01:00
Lemongrass3110
4cf3794afd Fixed VIP mode compilation
That fix was included in #7404 already... :-/
2022-11-07 11:36:29 +01:00
Lemongrass3110
4b16e4b020 Initial implementation of the goldpc timer
Fixes #6912

Thanks to @Balferian
2022-11-07 01:50:44 +01:00
13 changed files with 483 additions and 1 deletions

View File

@ -175,3 +175,19 @@ feature.stylist: on
// If this is allowed the "nosave" mapflag is still being respected
// and may prevent players from warping back into the instance.
//feature.instance_allow_reconnect: yes
// 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: 3600 (1h)
feature.goldpc_time: 3600
// How many points can a player have at maximum?
// Default: 300
feature.goldpc_max_points: 300
// Should being VIP double the points a player gets? (Note 1)
// Default: yes
feature.goldpc_vip: yes

279
npc/other/goldpc.txt Normal file
View File

@ -0,0 +1,279 @@
//===== rAthena Script =======================================
//= Gold PC Bonus NPC
//===== Description: =========================================
//= NPC that can be spawned via the Gold PC Timer Button.
//===== Changelog: ===========================================
//= 1.0 Initial release [Lemongrass]
//= 1.1 Replay version [eppc0330]
//= 1.2 Translation of the replay version [Lemongrass]
//= 1.3 Cleanup of NPC logic [Lemongrass]
//= 1.4 Added replay version of buff NPC [eppc0330]
//============================================================
prontera,0,0,0 script Goldpoint Manager::GOLDPCCAFE 4_F_02,{
// ID:AMOUNT:PRICE
setarray .items$[1],
"25464:1:2", // World_Tour_Ticket 1
"23919:1:10", // K_Secret_Key 1
"23919:11:100",// K_Secret_Key 11
"23919:33:300";// K_Secret_Key 33
mes "[Goldpoint Manager]";
mes "You currently have ^0000ff"+Goldpc_Points+"^000000 points.";
mes "What reward do you want?";
next;
.@menu$ = "View current points";
for(.@i = 1; .@i < getarraysize(.items$); .@i++) {
explode(.@array$, .items$[.@i], ":");
.@cost = atoi(.@array$[2]);
.@menu$ += ":" + .@cost + " points gift";
if( Goldpc_Points < .@cost ){
.@menu$ += " ^ff0000(not enough points)^000000";
}
}
.@s = select(.@menu$)-1;
if(.@s == 0) {
mes "[Goldpoint Manager]";
mes "You currently have ^0000ff"+Goldpc_Points+"^000000 points.";
close;
}
explode(.@array$, .items$[.@s], ":");
.@itemid = atoi(.@array$[0]);
.@amount = atoi(.@array$[1]);
.@cost = atoi(.@array$[2]);
if(Goldpc_Points < .@cost) {
mes "[Goldpoint Manager]";
mes "You have ^0000ff"+Goldpc_Points+"^000000 points remaining.";
mes "You cannot get the prize with this amount of points.";
close;
}
mes "[Goldpoint Manager]";
mes "You chose the "+.@cost+" points gift. We will reward you immediately.";
Goldpc_Points -= .@cost;
getitem .@itemid,.@amount;
mes "You have ^0000ff"+Goldpc_Points+"^000000 points remaining.";
close;
}
prontera,146,93,5 script 프버방시피 4_M_MANAGER,{
mes "[프버방시피]";
mes "여~ 계속 보게 되는군 친구.";
mes "별로 소개도 필요없을 정도로";
mes "많이 본 것 같지만 아무튼...";
mes "..입아프게 말하는 것도 귀찮고,";
mes "이미 익히들 잘 알고 있을거라고";
mes "생각하니 간단하게 이야기할게.";
next;
mes "[프버방시피]";
mes "자네가 있는 장소에 따라서,";
mes "나는 자네에게 여러가지";
mes "서비스를 해 줄 예정이야.";
next;
mes "[프버방시피]";
mes "아무튼 자네가 지금 서비스를";
mes "받을 수 있는가 체크를 해";
mes "보도록 하겠어. 잠깐만";
mes "기다려봐.";
next;
if(vip_status(VIP_STATUS_ACTIVE)==1||getgroupid()==99)
goto VIP; //Custom. In KRo there's two PC cafe grade : gold and silver.
else
goto Normal;
Normal:
mes "[프버방시피]";
mes "애석하게도 자네는 서비스를";
mes "받을 수 있는 곳에 존재하고";
mes "있지않군... 정 서비스를 받고";
mes "싶다면 다른 장소에서 컨택트";
mes "하도록 해.";
next;
mes "[프버방시피]";
mes "거 왜, 많은 사람들이 모여서";
mes "각자 다른 세계와 조우하는 그";
mes "장소 있잖아? 거기로 가서";
mes "이쪽 세계로 들어오란 말야.";
next;
mes "[프버방시피]";
mes "그 때 다시 이야기";
mes "하도록 하지. 좋은 하루되게.";
close;
Vip:
// ID:갯수:가격:이름:조사
setarray .items$[1],
"14529:10:2000:을", //탐욕스크롤
"12274:1:10000:을", //대환단
"12275:1:10000:을", //태청단
"12262:10:10000:를"; //마패
mes "[프버방시피]";
mes "오케이. 자네는 서비스를 받을";
mes "수 있는 장소...거기서 등급을";
mes "나눠보자면 골드 등급인가.";
mes "탐욕 스크롤, 대환단, 태청단,";
mes "마패를 받을 수 있는데...";
next;
mes "[프버방시피]";
mes "각자 탐욕 스크롤이 2000제니.";
mes "대환단이 10000제니";
mes "태청단이 10000제니";
mes "마패가 10000제니!";
mes "자아, 자네는 이중에 뭘 받고";
mes "싶어?";
next;
for(.@i = 1; .@i < getarraysize(.items$); .@i++) {
explode(.@array$, .items$[.@i], ":");
.@menu$ += ":"+getitemname(atoi(.@array$[0]));
}
.@s = select(.@menu$+":받지 않는다.")-1;
if(.@s == getarraysize(.items$)) {
mes "[프버방시피]";
mes "확고한 인간이로군. 오케이.";
mes "뭐 강요할 생각은 없다네.";
mes "그럼 좋은 하루되게나.";
close;
}
explode(.@array$, .items$[.@s], ":");
.@itemid = atoi(.@array$[0]);
.@amount = atoi(.@array$[1]);
.@cost = atoi(.@array$[2]);
.@name$ = getitemname(atoi(.@array$[0]));
.@part$ = (.@array$[3]);
if(zeny < .@cost) {
mes "[프버방시피]";
mes "애석하게도 자넨 "+.@cost+"제니라는";
mes "돈도 없구만... 서비스받기는";
mes "글렀어. 아무리 서비스라지만";
mes "그렇게 정해졌으니 공짜로 해";
mes "줄 수는 없다네.";
close;
}
if(countitem(.@itemid) > 0) {
mes "[프버방시피]";
mes "애석하게도 음... 자네는";
mes "이미 "+.@name$+""+.@part$+" 하나";
mes "가지고 있구만. 내가 이야기";
mes "안했었나? 아..이거 원 요즘";
mes "건망증이 늘어서 말이지.";
mes "핫핫핫.";
next;
mes "[프버방시피]";
mes "좌우지간, 물건이 많지는 않은";
mes "관계로 물건을 소지하고 있는";
mes "사람에게는 지급 할 수가 없어.";
next;
mes "[프버방시피]";
mes "다음 기회를 이용해 달라구.";
mes "다음에 또 보자구~!";
close;
}
mes "[프버방시피]";
mes "오케이. 잘 생각했어. 정말";
mes "탁월한 선택이야. 핫핫핫.";
mes "잘 쓰도록 하라구~";
set Zeny, Zeny - .@cost;
getitem .@itemid,.@amount;
next;
mes "[프버방시피]";
mes "그리고... 약속의 서비스다-!";
next;
mes "[프버방시피]";
mes "여기서 골드 등급의 손님을";
mes "위한 깜짝 선택! 서비스 4가지";
mes "중에 하나를 선택가능!";
next;
mes "[프버방시피]";
mes "첫 번째, ^FF0000STR+8, AGI+6, DEX+4,";
mes "^FF0000ATK+32, FLEE+5!";
mes "^000000두 번째, ^FF0000INT+8, DEX+6,";
mes "^FF0000VIT+4, MATK+40!^000000";
next;
mes "[프버방시피]";
mes "세 번째, ^FF0000DEX+8, AGI+6, LUK+4,";
mes "^FF0000ATK+24, MATK+24!";
mes "^000000네 번째, ^FF0000올+6 ATK+24, MATK+24!!^000000";
next;
mes "[프버방시피]";
mes "넷 중 뭘 받을래!";
next;
.@s2 = (select("첫 번째:두 번째:세 번째:네 번째"));
mes "[프버방시피]";
mes "이야아아아아아아압!";
if(.@s2 == 1) {
sc_start SC_STRFOOD,5400000,8;
sc_start SC_AGIFOOD,5400000,6;
sc_start SC_DEXFOOD,5400000,4;
sc_start SC_ATKPOTION,5400000,32;
sc_start SC_FLEEFOOD,5400000,5;
} else if(.@s2 == 2) {
sc_start SC_INTFOOD,5400000,8;
sc_start SC_DEXFOOD,5400000,6;
sc_start SC_VITFOOD,5400000,4;
sc_start SC_MATKPOTION,5400000,40;
} else if(.@s2 == 3) {
sc_start SC_DEXFOOD,5400000,8;
sc_start SC_AGIFOOD,5400000,6;
sc_start SC_LUKFOOD,5400000,4;
sc_start SC_ATKPOTION,5400000,24;
sc_start SC_MATKPOTION,5400000,24;
} else {
sc_start SC_STRFOOD,5400000,6;
sc_start SC_AGIFOOD,5400000,6;
sc_start SC_VITFOOD,5400000,6;
sc_start SC_INTFOOD,5400000,6;
sc_start SC_DEXFOOD,5400000,6;
sc_start SC_LUKFOOD,5400000,6;
sc_start SC_ATKPOTION,5400000,24;
sc_start SC_MATKPOTION,5400000,24;
}
next;
mes "[프버방시피]";
mes "힘을 불어넣어주었어. 어때?";
mes "손해봤다는 생각은 죽어도";
mes "안들지? 핫핫핫. 글쎄 남는";
mes "남는 장사도 이렇게 남는";
mes "장사가 있을 수가 없대두.";
next;
mes "[프버방시피]";
mes "자 그럼 다음에 또~";
close;
}
alberta,104,60,5 duplicate(프버방시피) 프버방시피#alb 4_M_MANAGER
aldebaran,146,116,5 duplicate(프버방시피) 프버방시피#ald 4_M_MANAGER
amatsu,102,152,5 duplicate(프버방시피) 프버방시피#ama 4_M_MANAGER
ayothaya,212,173,5 duplicate(프버방시피) 프버방시피#ayo 4_M_MANAGER
brasilis,200,224,5 duplicate(프버방시피) 프버방시피#bra 4_M_MANAGER
comodo,199,149,5 duplicate(프버방시피) 프버방시피#com 4_M_MANAGER
dewata,202,188,5 duplicate(프버방시피) 프버방시피#dew 4_M_MANAGER
dicastes01,193,191,5 duplicate(프버방시피) 프버방시피#dic 4_M_MANAGER
einbroch,235,207,5 duplicate(프버방시피) 프버방시피#ein 4_M_MANAGER
geffen,126,64,5 duplicate(프버방시피) 프버방시피#gef 4_M_MANAGER
gonryun,156,122,5 duplicate(프버방시피) 프버방시피#gon 4_M_MANAGER
hugel,80,152,5 duplicate(프버방시피) 프버방시피#hug 4_M_MANAGER
izlude,125,148,5 duplicate(프버방시피) 프버방시피#izl 4_M_MANAGER
lighthalzen,167,97,5 duplicate(프버방시피) 프버방시피#lig 4_M_MANAGER
louyang,210,107,5 duplicate(프버방시피) 프버방시피#lou 4_M_MANAGER
malangdo,178,139,5 duplicate(프버방시피) 프버방시피#mld 4_M_MANAGER
malaya,234,218,5 duplicate(프버방시피) 프버방시피#mly 4_M_MANAGER
manuk,296,147,5 duplicate(프버방시피) 프버방시피#man 4_M_MANAGER
mid_camp,201,237,5 duplicate(프버방시피) 프버방시피#mid 4_M_MANAGER
mora,113,112,5 duplicate(프버방시피) 프버방시피#mra 4_M_MANAGER
morocc,164,255,5 duplicate(프버방시피) 프버방시피#mro 4_M_MANAGER
moscovia,220,191,5 duplicate(프버방시피) 프버방시피#mos 4_M_MANAGER
niflheim,206,179,5 duplicate(프버방시피) 프버방시피#nif 4_M_MANAGER
payon,184,102,5 duplicate(프버방시피) 프버방시피#pay 4_M_MANAGER
rachel,111,143,5 duplicate(프버방시피) 프버방시피#rah 4_M_MANAGER
splendide,201,153,5 duplicate(프버방시피) 프버방시피#spl 4_M_MANAGER
umbala,93,160,5 duplicate(프버방시피) 프버방시피#umb 4_M_MANAGER
veins,210,109,5 duplicate(프버방시피) 프버방시피#vei 4_M_MANAGER
yuno,149,187,5 duplicate(프버방시피) 프버방시피#yun 4_M_MANAGER

View File

@ -178,6 +178,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

View File

@ -11389,6 +11389,11 @@ static const struct _battle_data {
{ "feature.instance_allow_reconnect", &battle_config.instance_allow_reconnect, 0, 0, 1, },
#endif
{ "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>
};

View File

@ -744,6 +744,11 @@ struct Battle_Config
int feature_banking_state_enforce;
int instance_allow_reconnect;
int feature_goldpc_active;
int feature_goldpc_time;
int feature_goldpc_max_points;
int feature_goldpc_vip;
#include <custom/battle_config_struct.inc>
};

View File

@ -307,9 +307,32 @@ int chrif_save(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 );
// If a player logs out or starts autotrade, stop counting
delete_timer( sd->goldpc_tid, pc_goldpc_update );
sd->goldpc_tid = INVALID_TIMER;
}
}else{
// Invalid timer anyway
sd->goldpc_tid = INVALID_TIMER;
}
}
//Saving of registry values.
if (sd->vars_dirty)
intif_saveregistry(sd);
@ -1575,6 +1598,9 @@ void chrif_parse_ack_vipActive(int fd) {
clif_displaymessage(sd->fd,msg_txt(sd,438));
}
}
clif_goldpc_info( *sd );
// Show info if status changed
if (((flag&0x4) || changed) && !sd->vip.disableshowrate) {
clif_display_pinfo( *sd );

View File

@ -11179,6 +11179,9 @@ void clif_parse_LoadEndAck(int fd,map_session_data *sd)
channel_mjoin(sd); //join new map
clif_pk_mode_message(sd);
// Update the client
clif_goldpc_info( *sd );
}
if( sd->guild && ( battle_config.guild_notice_changemap == 2 || guild_notice ) ){
@ -25236,6 +25239,70 @@ void clif_set_npc_window_pos_percent(map_session_data& sd, int x, int y)
#endif // PACKETVER_MAIN_NUM >= 20220504
}
void clif_goldpc_info( map_session_data& sd ){
#if PACKETVER_MAIN_NUM >= 20140508 || PACKETVER_RE_NUM >= 20140508 || defined(PACKETVER_ZERO)
const static int32 client_max_seconds = 3600;
if( battle_config.feature_goldpc_active ){
struct PACKET_ZC_GOLDPCCAFE_POINT p = {};
p.PacketType = HEADER_ZC_GOLDPCCAFE_POINT;
p.isActive = true;
if( battle_config.feature_goldpc_vip && pc_isvip( &sd ) ){
p.mode = 2;
}else{
p.mode = 1;
}
p.point = (int32)pc_readparam( &sd, SP_GOLDPC_POINTS );
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
remaining += ( remaining % 1000 );
p.playedTime = (int32)( client_max_seconds - ( remaining / 1000 ) );
}else{
p.playedTime = 0;
}
}else{
p.playedTime = client_max_seconds;
}
clif_send( &p, sizeof( p ), &sd.bl, SELF );
}
#endif
}
void clif_parse_dynamic_npc( int fd, 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->name, sizeof( p->name ) ) == 0 ){
safestrncpy( npcname, p->name, 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 );
clif_dynamicnpc_result( *sd, DYNAMICNPC_RESULT_UNKNOWNNPC );
return;
}
if( npc_duplicate_npc_for_player( *nd, *sd ) != nullptr ){
clif_dynamicnpc_result( *sd, DYNAMICNPC_RESULT_SUCCESS );
}
#endif
}
/*==========================================
* Main client packet processing function
*------------------------------------------*/

View File

@ -1257,4 +1257,6 @@ void clif_set_npc_window_size(map_session_data& sd, int width, int height);
void clif_set_npc_window_pos(map_session_data& sd, int x, int y);
void clif_set_npc_window_pos_percent(map_session_data& sd, int x, int y);
void clif_goldpc_info( map_session_data& sd );
#endif /* CLIF_HPP */

View File

@ -2108,6 +2108,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

View File

@ -505,6 +505,7 @@ enum _sp {
SP_CASHPOINTS, SP_KAFRAPOINTS,
SP_PCDIECOUNTER, SP_COOKMASTERY,
SP_ACHIEVEMENT_LEVEL,
SP_GOLDPC_POINTS,
// Mercenaries
SP_MERCFLEE=165, SP_MERCKILLS=189, SP_MERCFAITH=190,

View File

@ -2286,6 +2286,38 @@ bool pc_set_hate_mob(map_session_data *sd, int pos, struct block_list *bl)
return true;
}
TIMER_FUNC(pc_goldpc_update){
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?
int64 points = pc_readparam( sd, SP_GOLDPC_POINTS );
if( battle_config.feature_goldpc_vip && pc_isvip( sd ) ){
points += 2;
}else{
points += 1;
}
// Reset the seconds
pc_setreg2( sd, GOLDPC_SECONDS_VAR, 0 );
// Update the points and trigger a new timer if necessary
pc_setparam( sd, SP_GOLDPC_POINTS, points );
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.
@ -2394,6 +2426,15 @@ void pc_reg_received(map_session_data *sd)
clif_instance_info( *sd );
#endif
if( battle_config.feature_goldpc_active && pc_readreg2( sd, GOLDPC_POINT_VAR ) < battle_config.feature_goldpc_max_points && !sd->state.autotrade ){
sd->goldpc_tid = add_timer( gettick() + ( battle_config.feature_goldpc_time - pc_readreg2( sd, GOLDPC_SECONDS_VAR ) ) * 1000, pc_goldpc_update, sd->bl.id, (intptr_t)nullptr );
#ifndef VIP_ENABLE
clif_goldpc_info( *sd );
#endif
}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);
@ -10195,6 +10236,7 @@ int64 pc_readparam(map_session_data* sd,int64 type)
#endif
case SP_CRIT_DEF_RATE: val = sd->bonus.crit_def_rate; break;
case SP_ADD_ITEM_SPHEAL_RATE: val = sd->bonus.itemsphealrate2; break;
case SP_GOLDPC_POINTS: val = pc_readreg2( sd, GOLDPC_POINT_VAR ); break;
default:
ShowError("pc_readparam: Attempt to read unknown parameter '%lld'.\n", type);
return -1;
@ -10446,6 +10488,28 @@ bool pc_setparam(map_session_data *sd,int64 type,int64 val_tmp)
sd->cook_mastery = val;
pc_setglobalreg(sd, add_str(COOKMASTERY_VAR), sd->cook_mastery);
return true;
case SP_GOLDPC_POINTS:
val = cap_value( val, 0, battle_config.feature_goldpc_max_points );
pc_setreg2( sd, GOLDPC_POINT_VAR, val );
// If you do not check this, some funny things happen (circle logics, timer mismatches, etc...)
if( !sd->state.connect_new ){
// Make sure to always delete the timer
if( sd->goldpc_tid != INVALID_TIMER ){
delete_timer( sd->goldpc_tid, pc_goldpc_update );
sd->goldpc_tid = INVALID_TIMER;
}
// If the system is enabled and the player can still earn some points restart the timer
if( battle_config.feature_goldpc_active && val < battle_config.feature_goldpc_max_points && !sd->state.autotrade ){
sd->goldpc_tid = add_timer( gettick() + ( battle_config.feature_goldpc_time - pc_readreg2( sd, GOLDPC_SECONDS_VAR ) ) * 1000, pc_goldpc_update, sd->bl.id, (intptr_t)nullptr );
}
// Update the client
clif_goldpc_info( *sd );
}
return true;
default:
ShowError("pc_setparam: Attempted to set unknown parameter '%lld'.\n", type);
return false;
@ -15866,6 +15930,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);

View File

@ -65,6 +65,12 @@ class MapGuild;
#define ATTENDANCE_DATE_VAR "#AttendanceDate"
#define ATTENDANCE_COUNT_VAR "#AttendanceCounter"
#define ACHIEVEMENTLEVEL "AchievementLevel"
#ifndef GOLDPC_POINT_VAR
#define GOLDPC_POINT_VAR "Goldpc_Points"
#endif
#ifndef GOLDPC_SECONDS_VAR
#define GOLDPC_SECONDS_VAR "Goldpc_Seconds"
#endif
//Total number of classes (for data storage)
#define CLASS_COUNT (JOB_MAX - JOB_NOVICE_HIGH + JOB_MAX_BASIC)
@ -941,6 +947,8 @@ public:
s_macro_detect macro_detect;
std::vector<uint32> party_booking_requests;
int goldpc_tid;
};
extern struct eri *pc_sc_display_ers; /// Player's SC display table
@ -1752,4 +1760,6 @@ void pc_macro_reporter_process(map_session_data &sd, int32 reporter_account_id =
void pc_reputation_generate();
#endif
TIMER_FUNC(pc_goldpc_update);
#endif /* PC_HPP */

View File

@ -613,6 +613,7 @@
export_parameter(PCDIECOUNTER_VAR, SP_PCDIECOUNTER);
export_parameter(COOKMASTERY_VAR, SP_COOKMASTERY);
export_parameter(ACHIEVEMENTLEVEL, SP_ACHIEVEMENT_LEVEL);
export_parameter(GOLDPC_POINT_VAR, SP_GOLDPC_POINTS);
export_constant2("bMaxHP",SP_MAXHP);
export_constant2("bMaxSP",SP_MAXSP);