-
Posts
111 -
Joined
-
Last visited
Content Type
Profiles
Forums
Downloads
Jobs Available
Server Database
Third-Party Services
Top Guides
Store
Crowdfunding
Posts posted by Forshaken
-
-
On 9/25/2021 at 12:01 PM, Easycore said:
New Version:
Working on latest Git: 6672bf- Refactored 'item_vending.txt' to YAML Format 'item_vending_db.yml'.
- Fixed an issue regarding bound items in the buyer's inventory.
- Added a config to enable/disable buying with bounded items.
- Prevent buying if seller has the Max Item in the inventory (30,000 ea).
- Added GetComma for a better visualization of the amount of zeny received (Vending Report).
- Code clean-up.
Status: Pending Approval.
Waiting for approval

@Easycore I suggest to post it on your website sir
for your free release.
-
4 minutes ago, Eross said:
Hi ! can anyone edit my this script .. I made a share exp for event MOTD . but I need to check if the member is on the same map with the mob killer because every time I kill a monster an exp applies on members wherever they are. Thanks a lot guys
OnNPCKillEvent: query_sql ("SELECT `exp` FROM `party` WHERE `party_id` = "+ getcharid(1), [email protected]); if(killedrid!=$MobTypeLow && killedrid!=$MobTypeMid && killedrid!=$MobTypeHard ) { end; } [email protected]$ = strcharinfo(3); .mobid = killedrid; if ([email protected]) {addrid(2,0,getcharid(1));} dispbottom "[Monster of the Day]: Experience Gained Base:"+strmobinfo(6,.mobid)+" Job:"+strmobinfo(7,.mobid)+""; set BaseExp,(BaseExp+strmobinfo(6,.mobid)); set JobExp,(JobExp+strmobinfo(7,.mobid)); end;What is your basis then?
- Location of party leader ?
- Specific location chosen by you? -
3 hours ago, Eross said:
Yes but how to make it affect bonus by not just killing the mob ...
try using this sample script
- script killplayerbonus -1,{
OnNPCKillEvent:
OnPCKillEvent:
if(isequipped(Beholder_Ring_ID)){
BaseExp += n;
JobExp +=n;
end;
}
end;
} -
On 9/13/2021 at 6:23 PM, exyoupjkbrxd said:
Hello everyone, I'm trying to make a script for a NPC to change the player's rates with SC_EXPBOOST and SC_ITEMBOOST. I'm new to scripting and there might be a better way to make what I want but it works and I'm happy that I was able to make it work.
I've got a menu working
mes "[Rate Professor]"; mes "You can change the rate you are using."; mes "Your current rate is ^777777"+rate$+"/"+rate$+"/"+drop$+"^000000"; mes "Please select the rate you want:"; // -------------------------------------------------- // Main Menu: // -------------------------------------------------- menu "Change Exp Rates",EXPMenu, "Change Drop Rate",DROPMenu, "Cancel",Cancel; // -------------------------------------------------- EXPMenu: // -------------------------------------------------- menu " 1x/1x EXP",e1x, " 2x/2x EXP",e2x; // -------------------------------------------------- DROPMenu: // -------------------------------------------------- menu " 1x DROP",d1x, " 2x DROP",d2x;The Change Exp Rates works with those lines :
e1x: sc_end SC_EXPBOOST; set rate$ , "1x";end; e2x: sc_end SC_EXPBOOST; sc_start SC_EXPBOOST,-1,100; set rate$ , "2x";end;If the player select 1x, the script will remove the SC_EXPBOOST and set the variable rate$ to x1, which is shown in the NPC's message. I've got it working till 20x and I don't have any problem changing rates, removing the buff, login out/login in.
But whenever I try to change the drop rate with :
d1x: sc_end SC_ITEMBOOST; set drop$ , "1x";end; d2x: sc_end SC_ITEMBOOST; sc_start SC_ITEMBOOST,-1,100; set drop$ , "2x";end;I get an error:
[Error]: npc_parsesrcfile: Unknown syntax in file 'npc/custom/Rate Changer.txt', line '101'. Stopping... * w1=d1x: sc_end SC_ITEMBOOST; set drop$ , "1x";end; * w2= * w3= * w4=When the "d1x" line (or any other line like those) are included in the script, the NPC is not spawn in the world. When I comment them out, the NPC spawn without any issue. I try to find a way to make it work but I couldn't and I don't really understand the error message. Never got that error when I was writing the EXP part. Something else that I try was to put the effect from the bubble gum item (ID:12210 = sc_start SC_ITEMBOOST,1800000,200;) in the script but I still got the same error but with the bubble gum script.
If someone could tell me where the error is or what I'm doing wrong it would be greatly appreciated.
Thank you
can you paste your whole script here
-
On 9/14/2021 at 6:12 PM, powkda said:
Good afternoon, I got the dice event here, but it's giving the following error on the following line:
You have been issued a warning. Before you can post again, you must acknowledge the warning.
.@size = getmapunits(BL_PC,.@players,"quiz_02");
how could I reverse this error?
try using getmapusers instead of getmapunits
-
14 hours ago, Eross said:
Navigate Beholder Ring in db/pre-re/item_db.txt then simply change the exp bonus value of beholder ring from that file.
-
//==============================================================================// //= Script Release : Job Changer + Max Leveler [ Version 1.5 ] //==================================By==========================================// //= ManiacSociety //==============================================================================// //= Idea Came From : ManiacSociety //= Helper : Emistry & Kenpachi //==============================================================================// //= D E S C R I P T I O N S //==============================================================================// // -- 1. Character can choose a Job which he like to be. // -- 2. This NPC only have 1 Time Usage. // If it is set to Account Based then that account can use 1 times. // If it is set to Character Based then all new character can use 1 times. // -- 3. Complete skills / Skill Points will be given if it is set to be. // -- 4. Base Level and Job Level will be given upon Job Change. //==============================================================================// //= V E R S I O N S //==============================================================================// // -- [ 1.5 ] : Added Configuration for Account Based / Character Based Settings // -- [ 1.4 ] : Added Baby Classes + 3rd Job Classes. // -- [ 1.3 ] : Added Configuration Option , 4 Announce Option , Informations. // -- [ 1.2 ] : Simplified Scripts + Shorten the Scripts. // -- [ 1.1 ] : Added New Job Change Option. // -- [ 1.0 ] : Simple Login Auto Max Level + Job Changer. //==============================================================================// //= R U L E S //==============================================================================// // -- 1. Do not use for exchanging purpose. // -- 2. Do not claim it as yours. // -- 3. Do not change or remove the credits. // -- 4. Do not sell the script in order to get paid. // -- 5. Do not re-sharing upon modified without permission. //==============================================================================// new_1-1,57,124,1 script Instant Job Master 651,{ if (#FreeInstaJob == 1) { mes "[Starter NPC]"; mes "You can only use my services"; mes "once per account, sorry."; close; } if (BaseClass == Job_Novice) goto Main_Menu; // -- Configuration Option set .npcname$,"[ ^0000FF Class Helper ^000000 ]"; set .InfoMenu,0; // Classes Informations Option [ 0 - Disable / 1 - Enable ] set .1stClassMenu,0; // First Job Class Option [ 0 - Disable / 1 - Enable ] set .2ndClassMenu,0; // Second Job Class Option [ 0 - Disable / 1 - Enable ] set .High1stClassMenu,0; // High 1st Class Option [ 0 - Disable / 1 - Enable ] set .Trans2ndClassMenu,1; // Transcendent Class Option [ 0 - Disable / 1 - Enable ] set .Trans3rdClassMenu,0; // Third Job Class Option [ 0 - Disable / 1 - Enable ] set .ExpandedClassMenu,1; // Expanded Class Option [ 0 - Disable / 1 - Enable ] set .BabyClassMenu,0; // Baby Job Class Option [ 0 - Disable / 1 - Enable ] set .Baby3rdClassMenu,0; // Baby Third Job Class Option [ 0 - Disable / 1 - Enable ] set .allskills,1; // Complete Skills Option [ 0 - Disable / 1 - Enable ] Main_Menu: mes "[Instant Job Master]"; mes "Nice to meet you "+ strcharinfo ( 0 ) +", my name is Instant Job Master"; mes "Welcome to ^E066FFScarsRO!^000000"; next; switch(select(( .InfoMenu == 0 )?"":"Classes Information", ( .1stClassMenu == 0 )?"":"First Job Classes", ( .2ndClassMenu == 0 )?"":"Second Job Classes", ( .High1stClassMenu == 0 )?"":"High First Job Classes", ( .Trans2ndClassMenu == 1 )?"":"Transcendent Job Classes", ( .Trans3rdClassMenu == 0 )?"":"Third Job Classes", ( .ExpandedClassMenu == 0 )?"":"Expanded Job Classes", ( .BabyClassMenu == 0 )?"":"Baby Normal Job Classes", ( .Baby3rdClassMenu == 0 )?"":"^Baby Third Job Classes", "^FF0000Sorry, i admire nobody....^000000")) { Case 1: goto Classes_info; Case 2: goto FirstJob_Classes; Case 3: goto SecondJob_Classes; Case 4: goto HighFirstJob_Classes; Case 5: goto TransSecondJob_Classes; Case 6: goto TransThirdJob_Classes; Case 7: goto ExpandedJob_Classes; Case 8: goto BabyJob_Classes; Case 9: goto BabyThirdJob_Classes; Case 10: close; } FirstJob_Classes: mes .npcname$; mes "So, i give you a chance now. Which Classes will you choose to join ? Tell me your desired Classes."; next; switch(select("Swordman", "Magician", "Archer", "Acolyte", "Merchant", "Thief", "Back")) { // --- callsub Job_Changing,<JOB>,<BaseLv>,<JobLv>,<Skill>,<Announce>; Case 1: callsub Job_Changing,1,99,50,60,"All"; Case 2: callsub Job_Changing,2,99,50,60,"All"; Case 3: callsub Job_Changing,3,99,50,60,"All"; Case 4: callsub Job_Changing,4,99,50,60,"All"; Case 5: callsub Job_Changing,5,99,50,60,"All"; Case 6: callsub Job_Changing,6,99,50,60,"All"; Case 7: goto Main_Menu; } HighFirstJob_Classes: mes .npcname$; mes "So, i give you a chance now. Which Classes will you choose to join ? Tell me your desired Classes."; next; switch(select("High Swordman", "High Magician", "High Archer", "High Acolyte", "High Merchant", "High Thief", "Back")) { // --- callsub Job_Changing,<JOB>,<BaseLv>,<JobLv>,<Skill>,<Announce>; Case 1: callsub Job_Changing,4002,99,50,60,"All"; Case 2: callsub Job_Changing,4003,99,50,60,"All"; Case 3: callsub Job_Changing,4004,99,50,60,"All"; Case 4: callsub Job_Changing,4005,99,50,60,"All"; Case 5: callsub Job_Changing,4006,99,50,60,"All"; Case 6: callsub Job_Changing,4007,99,50,60,"All"; Case 7: goto Main_Menu; } SecondJob_Classes: mes .npcname$; mes "So, i give you a chance now. Which Classes will you choose to join ? Tell me your desired Classes."; next; switch(select("Knight", "Priest", "Wizard", "Blacksmith", "Hunter", "Assassin", "Crusader", "Monk", "Sage", "Rogue", "Alchemist", ( Sex == 0 )?"":"Dancer", ( Sex == 1 )?"":"Bard", "Back")) { // --- callsub Job_Changing,<JOB>,<BaseLv>,<JobLv>,<Skill>,<Announce>; Case 1: callsub Job_Changing,7,99,50,110,"All"; Case 2: callsub Job_Changing,8,99,50,110,"All"; Case 3: callsub Job_Changing,9,99,50,110,"All"; Case 4: callsub Job_Changing,10,99,50,110,"All"; Case 5: callsub Job_Changing,11,99,50,110,"All"; Case 6: callsub Job_Changing,12,99,50,110,"All"; Case 7: callsub Job_Changing,14,99,50,110,"All"; Case 8: callsub Job_Changing,15,99,50,110,"All"; Case 9: callsub Job_Changing,16,99,50,110,"All"; Case 10: callsub Job_Changing,17,99,50,110,"All"; Case 11: callsub Job_Changing,18,99,50,110,"All"; Case 12: callsub Job_Changing,20,99,50,110,"All"; Case 13: callsub Job_Changing,19,99,50,110,"All"; Case 14: goto Main_Menu; } TransSecondJob_Classes: mes .npcname$; mes "So, i give you a chance now. Which Classes will you choose to join ? Tell me your desired Classes."; next; switch(select("Lord Knight", "High Priest", "High Wizard", "Whitesmith", "Sniper", "Assassin Cross", "Paladin", "Champion", "Professor", "Stalker", "Creator", ( Sex == 0 )?"":"Gypsy", ( Sex == 1 )?"":"Clowm", "Back")) { // --- callsub Job_Changing,<JOB>,<BaseLv>,<JobLv>,<Skill>,<Announce>; Case 1: callsub Job_Changing,4008,99,70,127,"All"; Case 2: callsub Job_Changing,4009,99,70,127,"All"; Case 3: callsub Job_Changing,4010,99,70,127,"All"; Case 4: callsub Job_Changing,4011,99,70,127,"All"; Case 5: callsub Job_Changing,4012,99,70,127,"All"; Case 6: callsub Job_Changing,4013,99,70,127,"All"; Case 7: callsub Job_Changing,4015,99,70,127,"All"; Case 8: callsub Job_Changing,4016,99,70,127,"All"; Case 9: callsub Job_Changing,4017,99,70,127,"All"; Case 10: callsub Job_Changing,4018,99,70,127,"All"; Case 11: callsub Job_Changing,4019,99,70,127,"All"; Case 12: callsub Job_Changing,4021,99,70,127,"All"; Case 13: callsub Job_Changing,4020,99,70,127,"All"; Case 14: goto Main_Menu; } ExpandedJob_Classes: mes .npcname$; mes "So, i give you a chance now. Which Classes will you choose to join ? Tell me your desired Classes."; next; switch(select("Super Novice", "Back")) { // --- callsub Job_Changing,<JOB>,<BaseLv>,<JobLv>,<Skill>,<Announce>; Case 1: callsub Job_Changing,23,255,120,110,"All"; Case 2: callsub Job_Changing,24,255,120,600,"All"; Case 3: callsub Job_Changing,25,255,120,60,"All"; Case 4: callsub Job_Changing,4046,255,120,60,"All"; Case 5: callsub Job_Changing,4047,255,120,110,"All"; Case 6: callsub Job_Changing,4049,255,120,110,"All"; Case 7: goto Main_Menu; } Job_Changing: mes .npcname$; mes "You are now a part of ^FF0000"+jobname(getarg(0))+"^000000."; if (compare(getarg(4),"All")){ announce "[ "+strcharinfo(0)+" ] has changed to [ "+jobname(getarg(0))+" ].",bc_all,0x76EE00; } if (compare(getarg(4),"Map")){ announce "[ "+strcharinfo(0)+" ] has changed to [ "+jobname(getarg(0))+" ].",bc_map,0x76EE00; } if (compare(getarg(4),"Area")){ announce "[ "+strcharinfo(0)+" ] has changed to [ "+jobname(getarg(0))+" ].",bc_area,0x76EE00; } if (compare(getarg(4),"Self")){ announce "[ "+strcharinfo(0)+" ] has changed to [ "+jobname(getarg(0))+" ].",bc_self,0x76EE00; } jobchange getarg(0); set BaseLevel,getarg(1); set JobLevel,getarg(2); ResetSkill; ResetStatus; set SkillPoint,getarg(3); if ( .allskills == 1 ){ atcommand "@allskills"; set SkillPoint,0; } set #FreeInstaJob,1; percentheal 100,100; close; Classes_info: mes .npcname$; mes "=====[^76EE00 Swordman Classes ^000000]====="; mes " ^FF0000________________________________^000000"; mes "^4EEE94Description :^000000"; mes "Enthusiastic skills in sword fighting is a definite attraction to all teenagers. Easy to control and master character enables most players to be a great player."; mes " ^FF0000________________________________^000000"; next; mes .npcname$; mes "=====[^76EE00 Archer Classes ^000000]====="; mes " ^FF0000________________________________^000000"; mes "^4EEE94Description :^000000"; mes "Long ranged attack ability and special techniques of archers in defeating enemy often lure players to try this."; mes " ^FF0000________________________________^000000"; next; mes .npcname$; mes "=====[^76EE00 Mage Classes ^000000]====="; mes " ^FF0000________________________________^000000"; mes "^4EEE94Description :^000000"; mes "Fascinating element techniques involvement of nature in its abilities is truly amazing with their series of undefeatable magics."; mes " ^FF0000________________________________^000000"; next; mes .npcname$; mes "=====[^76EE00 Thief Classes ^000000]====="; mes " ^FF0000________________________________^000000"; mes "^4EEE94Description :^000000"; mes "Poisoning and dodging abilities will defeat most of the enemy. Maximum defensive and offensive ability caused this character to fearsome one."; mes " ^FF0000________________________________^000000"; next; mes .npcname$; mes "=====[^76EE00 Acolyte Classes ^000000]====="; mes " ^FF0000________________________________^000000"; mes "^4EEE94Description :^000000"; mes "A supportive character, most of the skills like helping will benefit to teammates who lead to teammates act like a terminator."; mes " ^FF0000________________________________^000000"; next; mes .npcname$; mes "=====[^76EE00 Merchant Classes ^000000]====="; mes " ^FF0000________________________________^000000"; mes "^4EEE94Description :^000000"; mes "Involving communication with other players that emphasizes on battles, intelligence in business dealing. His versatility made him must not be look down."; mes " ^FF0000________________________________^000000"; next; mes .npcname$; mes "=====[^76EE00 Super Novice ^000000]====="; mes " ^FF0000________________________________^000000"; mes "^4EEE94Description :^000000"; mes "A job who are Advanced after Novice Class. It look alike like a Novice but it is not. Beside that, it can learn most of the skills for all 1st Job Class."; mes " ^FF0000________________________________^000000"; next; mes .npcname$; mes "=====[^76EE00 Gunslinger ^000000]====="; mes " ^FF0000________________________________^000000"; mes "^4EEE94Description :^000000"; mes "The only Job class in RO who are using Gun as weapon. If are you a Gun Lover , there is no doubt you will choose this Job."; mes " ^FF0000________________________________^000000"; next; mes .npcname$; mes "=====[^76EE00 Ninja ^000000]====="; mes " ^FF0000________________________________^000000"; mes "^4EEE94Description :^000000"; mes "A mysterious Job Class , who alway processing Ancient Spells , look alike with Mage but not mage , good in PK , can evade very well during PK."; mes " ^FF0000________________________________^000000"; next; mes .npcname$; mes "=====[^76EE00 Taekwon ^000000]====="; mes " ^FF0000________________________________^000000"; mes "^4EEE94Description :^000000"; mes "Just like the name has mentioned. The only class in RO who are not using any Weapon. Attack enemy using barehand and foots. "; mes " ^FF0000________________________________^000000"; next; mes .npcname$; mes "=====[^76EE00 Star Gladiator ^000000]====="; mes " ^FF0000________________________________^000000"; mes "^4EEE94Description :^000000"; mes "A class who can use the power of the Sun / Star / Moon. By processing the power of Universe to gain a stronger Power."; mes " ^FF0000________________________________^000000"; next; mes .npcname$; mes "=====[^76EE00 Soul Linker ^000000]====="; mes " ^FF0000________________________________^000000"; mes "^4EEE94Description :^000000"; mes "Class that work like a Shaman, who able to recalling the soul of the dead from the underworld to Boost other class ability."; mes " ^FF0000________________________________^000000"; next; goto Main_Menu; OnInit: waitingroom " Instant Job Master",0; end; }
-
On 8/23/2021 at 7:07 AM, nmainoi said:
So there is bug with some ranged skills that they just ignore my skill_db range set, like this https://gyazo.com/ce0fa57e6e3cb455da48badbc4139757
those r all the references of that gif skill, bute there is other examples
try to edit your lua files inside LuaFiles514/Lua Files/skillinfoz
-
7 minutes ago, Eross said:
Yes I tried sir .. But every time I use fly wing in prontera the dispel still triggers .. It should be on warp only not on teleport
For portals you have to do what the first guy who replied to your question about "OnTouch" Event but for priest warp you have to edit src codes as far as i know.
-
On 8/26/2021 at 2:57 AM, ZodiacoHCK said:
Hello people!
I wanted to tell you that I have a problem trying to implement NAPSTER's PvP cell in my emulator. I have my emulator running stable in the latest master version available about 4 months ago.
the problem is that there are certain differences between my rathena codes and the diff code of the patch.
I have successfully implemented the BGex manually and I had no problems. but this pvp_cell has not succeeded.
I leave the patch that I am trying to put!
conf/battle/misc.conf | 39 +++++++++++++++++++++ conf/msg_conf/map_msg.conf | 4 +++ db/const.txt | 3 ++ src/map/atcommand.c | 8 ++--- src/map/battle.c | 30 ++++++++++++---- src/map/battle.h | 10 +++++- src/map/clif.c | 8 ++++- src/map/map.cpp | 46 +++++++++++++++++++++++-- src/map/map.h | 12 +++++-- src/map/pc.c | 86 ++++++++++++++++++++++++++++++++++++++++++---- src/map/pc.h | 2 ++ src/map/script_constants.h | 4 ++- src/map/skill.c | 3 +- src/map/unit.c | 47 ++++++++++++++++++++++++- 14 files changed, 274 insertions(+), 28 deletions(-) diff --git a/conf/battle/misc.conf b/conf/battle/misc.conf index 7c085fd41..37759b659 100644 --- a/conf/battle/misc.conf +++ b/conf/battle/misc.conf @@ -176,3 +176,42 @@ mail_delay: 1000 // Hides items from the player's favorite tab from being sold to a NPC. (Note 1) hide_fav_sell: no + +// Addon Cell PVP [Napster] +// Enable Deathmatch for cell pvp +// Default: 0 +// 0 = No +// 1 = Yes +cellpvp_deathmatch: 1 + +// Delay player alive deathmatch for cell pvp +// Default: 1000 (1 secand) +cellpvp_deathmatch_delay: 1000 + +// When player is dead recovery HP/SP Rate for cell pvp +// Default: 100 (recovery 100%) +deathmatch_hp_rate: 100 +deathmatch_sp_rate: 100 + +// Enable buff when player is dead for cell pvp +// Default: 1 +// 0 = No +// 1 = Yes +// Request core npc files use name "deathmatch_core" +cellpvp_autobuff: yes + +// Can atk player in party +// Default: 1 +// 0 = No +// 1 = Yes +cellpvp_party_enable: no + +// Can atk player in guild +// Default: 1 +// 0 = No +// 1 = Yes +cellpvp_guild_enable: no + +// When player move to cell pvp is delay walk out cooldown +// Default: 5000 (5 secand) +cellpvp_walkout_delay: 5000 \ No newline at end of file diff --git a/conf/msg_conf/map_msg.conf b/conf/msg_conf/map_msg.conf index 50306ef97..d3afebbc8 100644 --- a/conf/msg_conf/map_msg.conf +++ b/conf/msg_conf/map_msg.conf @@ -1664,3 +1664,7 @@ //Custom translations //import: conf/msg_conf/import/map_msg_eng_conf.txt + +// Addon Cell PVP [Napster] +1599: Walking failed. [%s] is cooling down. Wait %.1f minutes. +1600: Walking failed. [%s] is cooling down. Wait %d seconds. \ No newline at end of file diff --git a/db/const.txt b/db/const.txt index a10cc018b..46bf071f9 100644 --- a/db/const.txt +++ b/db/const.txt @@ -2313,3 +2313,6 @@ ARCWANDCLAN 2 GOLDENMACECLAN 3 CROSSBOWCLAN 4 JUMPINGCLAN 5 + +CELL_PVP 10 +CELL_CHKPVP 16 \ No newline at end of file diff --git a/src/map/atcommand.c b/src/map/atcommand.c index d8d52b9cc..c6bd4ce11 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -482,7 +482,7 @@ ACMD_FUNC(mapmove) clif_displaymessage(fd, msg_txt(sd,247)); // You are not authorized to warp to this map. return -1; } - if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { + if (sd->state.pvp || sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif_displaymessage(fd, msg_txt(sd,248)); // You are not authorized to warp from your current map. return -1; } @@ -830,11 +830,11 @@ ACMD_FUNC(load) nullpo_retr(-1, sd); m = map_mapindex2mapid(sd->status.save_point.map); - if (m >= 0 && map[m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { + if (sd->state.pvp && (m >= 0 && map[m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE))) { clif_displaymessage(fd, msg_txt(sd,249)); // You are not authorized to warp to your save map. return -1; } - if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { + if (sd->state.pvp && (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE))) { clif_displaymessage(fd, msg_txt(sd,248)); // You are not authorized to warp from your current map. return -1; } @@ -2054,7 +2054,7 @@ ACMD_FUNC(go) clif_displaymessage(fd, msg_txt(sd,247)); // You are not authorized to warp to this map. return -1; } - if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { + if (sd->state.pvp || sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif_displaymessage(fd, msg_txt(sd,248)); // You are not authorized to warp from your current map. return -1; } diff --git a/src/map/battle.c b/src/map/battle.c index e2d616bd9..ef7b5e9cd 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -7767,6 +7767,10 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f else return 0; // You can't target anything out of your duel } + else if( map_getcell( s_bl->m, s_bl->x, s_bl->y, CELL_CHKPVP ) && map_getcell( t_bl->m, t_bl->x, t_bl->y, CELL_CHKPVP ) ) // Addon Cell PVP [Napster] + { + state |= BCT_ENEMY; + } } if( map_flag_gvg(m) && !sd->status.guild_id && t_bl->type == BL_MOB && ((TBL_MOB*)t_bl)->mob_id == MOBID_EMPERIUM ) return 0; //If you don't belong to a guild, can't target emperium. @@ -7868,15 +7872,19 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f if( flag&BCT_PARTY || state&BCT_ENEMY ) { int s_party = status_get_party_id(s_bl); - if(s_party && s_party == status_get_party_id(t_bl)) - state |= BCT_PARTY; + if(s_party && s_party == status_get_party_id(t_bl) && !(battle_config.cellpvp_party_enable && map_getcell( t_bl->m, t_bl->x, t_bl->y, CELL_CHKPVP )) ) // Addon Cell PVP [Napster] + state |= BCT_PARTY; + else + state |= BCT_ENEMY; } if( flag&BCT_GUILD || state&BCT_ENEMY ) { int s_guild = status_get_guild_id(s_bl); int t_guild = status_get_guild_id(t_bl); - if(s_guild && t_guild && (s_guild == t_guild || (!(flag&BCT_SAMEGUILD) && guild_isallied(s_guild, t_guild)))) - state |= BCT_GUILD; + if(s_guild && t_guild && (s_guild == t_guild || (!(flag&BCT_SAMEGUILD) && guild_isallied(s_guild, t_guild))) && !(battle_config.cellpvp_guild_enable && map_getcell( t_bl->m, t_bl->x, t_bl->y, CELL_CHKPVP )) ) // Addon Cell PVP [Napster] + state |= BCT_GUILD; + else + state |= BCT_ENEMY; } } //end non pvp/gvg chk rivality @@ -8419,7 +8427,7 @@ static const struct _battle_data { { "change_party_leader_samemap", &battle_config.change_party_leader_samemap, 1, 0, 1, }, { "dispel_song", &battle_config.dispel_song, 0, 0, 1, }, { "guild_maprespawn_clones", &battle_config.guild_maprespawn_clones, 0, 0, 1, }, - { "hide_fav_sell", &battle_config.hide_fav_sell, 0, 0, 1, }, + { "hide_fav_sell", &battle_config.hide_fav_sell, 0, 0, 1, }, { "mail_daily_count", &battle_config.mail_daily_count, 100, 0, INT32_MAX, }, { "mail_zeny_fee", &battle_config.mail_zeny_fee, 2, 0, 100, }, { "mail_attachment_price", &battle_config.mail_attachment_price, 2500, 0, INT32_MAX, }, @@ -8427,10 +8435,20 @@ static const struct _battle_data { { "banana_bomb_duration", &battle_config.banana_bomb_duration, 0, 0, UINT16_MAX, }, { "guild_leaderchange_delay", &battle_config.guild_leaderchange_delay, 1440, 0, INT32_MAX, }, { "guild_leaderchange_woe", &battle_config.guild_leaderchange_woe, 0, 0, 1, }, - { "guild_alliance_onlygm", &battle_config.guild_alliance_onlygm, 0, 0, 1, }, + { "guild_alliance_onlygm", &battle_config.guild_alliance_onlygm, 0, 0, 1, }, { "feature.achievement", &battle_config.feature_achievement, 1, 0, 1, }, { "allow_bound_sell", &battle_config.allow_bound_sell, 1, 0, 1, }, + // Addon Cell PVP [Napster] + { "cellpvp_deathmatch", &battle_config.cellpvp_deathmatch, 1, 0, 1, }, + { "cellpvp_deathmatch_delay", &battle_config.cellpvp_deathmatch_delay, 1000, 0,INT_MAX, }, + { "deathmatch_hp_rate", &battle_config.deathmatch_hp_rate, 0, 0, 100, }, + { "deathmatch_sp_rate", &battle_config.deathmatch_sp_rate, 0, 0, 100, }, + { "cellpvp_autobuff", &battle_config.cellpvp_autobuff, 1, 0, 1, }, + { "cellpvp_party_enable", &battle_config.cellpvp_party_enable, 1, 0, 1, }, + { "cellpvp_guild_enable", &battle_config.cellpvp_guild_enable, 1, 0, 1, }, + { "cellpvp_walkout_delay", &battle_config.cellpvp_walkout_delay, 5000, 0,INT_MAX, }, + #include "../custom/battle_config_init.inc" }; diff --git a/src/map/battle.h b/src/map/battle.h index 37c86dfbb..abcb2b4a7 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -632,7 +632,15 @@ extern struct Battle_Config int guild_alliance_onlygm; int feature_achievement; int allow_bound_sell; - + // Addon Cell PVP [Napster] + int cellpvp_deathmatch; + int cellpvp_deathmatch_delay; + int deathmatch_hp_rate; + int deathmatch_sp_rate; + int cellpvp_autobuff; + int cellpvp_party_enable; + int cellpvp_guild_enable; + int cellpvp_walkout_delay; #include "../custom/battle_config_struct.inc" } battle_config; diff --git a/src/map/clif.c b/src/map/clif.c index e3d4a5abf..8bf9f93dc 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -10446,7 +10446,13 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) mail_clear(sd); - + + // Addon Cell PVP [Napster] + if( !sd->state.pvp && map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP) ) + map_pvp_area(sd, 1); + else if( sd->state.pvp && !map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP) ) + map_pvp_area(sd, 0); + /* Guild Aura Init */ if( sd->state.gmaster_flag ) { guild_guildaura_refresh(sd,GD_LEADERSHIP,guild_checkskill(sd->guild,GD_LEADERSHIP)); diff --git a/src/map/map.cpp b/src/map/map.cpp index 57486ac58..02013af02 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -115,7 +115,7 @@ static int block_free_count = 0, block_free_lock = 0; static struct block_list *bl_list[BL_LIST_MAX]; static int bl_list_count = 0; -#define MAP_MAX_MSG 1550 +#define MAP_MAX_MSG 1601 struct map_data map[MAX_MAP_PER_SERVER]; int map_num = 0; @@ -2092,7 +2092,10 @@ int map_quit(struct map_session_data *sd) { if (sd->state.buyingstore) idb_remove(buyingstore_getdb(), sd->status.char_id); - + // Addon Cell PVP [Napster] + if( sd->state.pvp && map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP ) ) + map_pvp_area(sd, 0); + pc_damage_log_clear(sd,0); party_booking_delete(sd); // Party Booking [Spiria] pc_makesavestatus(sd); @@ -3068,7 +3071,8 @@ int map_getcellp(struct map_data* m,int16 x,int16 y,cell_chk cellchk) return (cell.maelstrom); case CELL_CHKICEWALL: return (cell.icewall); - + case CELL_CHKPVP: // Addon Cell PVP [Napster] + return (cell.pvp); // special checks case CELL_CHKPASS: #ifdef CELL_NOSTACK @@ -3122,6 +3126,7 @@ void map_setcell(int16 m, int16 x, int16 y, cell_t cell, bool flag) case CELL_NOCHAT: map[m].cell[j].nochat = flag; break; case CELL_MAELSTROM: map[m].cell[j].maelstrom = flag; break; case CELL_ICEWALL: map[m].cell[j].icewall = flag; break; + case CELL_PVP: map[m].cell[j].pvp = flag; break; // Addon Cell PVP [Napster] default: ShowWarning("map_setcell: invalid cell type '%d'\n", (int)cell); break; @@ -4054,6 +4059,41 @@ int inter_config_read(const char *cfgName) return 0; } +// Addon Cell PVP [Napster] +int map_pvp_area(struct map_session_data* sd, bool flag) +{ + switch(flag) + { + case 1: + clif_map_property(&sd->bl, MAPPROPERTY_FREEPVPZONE, SELF); + if (sd->pvp_timer == INVALID_TIMER) { + map[sd->bl.m].cell_pvpuser++; + + sd->pvp_timer = add_timer(gettick()+200, pc_calc_pvprank_timer, sd->bl.id, 0); + sd->pvp_rank = 0; + sd->pvp_lastusers = 0; + sd->pvp_point = 5; + sd->pvp_won = 0; + sd->pvp_lost = 0; + sd->state.pvp = 1; + sd->pvpcan_walkout_tick = gettick(); + } + break; + default: + clif_pvpset(sd, 0, 0, 2); + map[sd->bl.m].cell_pvpuser--; + + if( sd->pvp_timer != INVALID_TIMER ) + delete_timer(sd->pvp_timer, pc_calc_pvprank_timer); + + sd->pvp_timer = INVALID_TIMER; + sd->state.pvp = 0; + break; + } + + return 0; +} + /*======================================= * MySQL Init *---------------------------------------*/ diff --git a/src/map/map.h b/src/map/map.h index fd5a6b046..e6687c1fa 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -521,7 +521,7 @@ typedef enum { CELL_NOCHAT, CELL_MAELSTROM, CELL_ICEWALL, - + CELL_PVP, } cell_t; // used by map_getcell() @@ -545,7 +545,7 @@ typedef enum { CELL_CHKNOCHAT, // Whether the cell denies Player Chat Window CELL_CHKMAELSTROM, // Whether the cell has Maelstrom CELL_CHKICEWALL, // Whether the cell has Ice Wall - + CELL_CHKPVP, // Addon Cell PVP [Napster] } cell_chk; struct mapcell @@ -564,7 +564,8 @@ struct mapcell novending : 1, nochat : 1, maelstrom : 1, - icewall : 1; + icewall : 1, + pvp : 1; // Addon Cell PVP [Napster] #ifdef CELL_NOSTACK unsigned char cell_bl; //Holds amount of bls in this cell. @@ -624,6 +625,7 @@ struct map_data { int npc_num; int users; int users_pvp; + int cell_pvpuser; // Addon Cell PVP [Napster] int iwall_num; // Total of invisible walls in this map struct map_flag { unsigned town : 1; // [Suggestion to protect Mail System] @@ -684,6 +686,7 @@ struct map_data { unsigned gvg_te : 1; // GVG WOE:TE. This was added as purpose to change 'gvg' for GVG TE, so item_noequp, skill_nocast exlude GVG TE maps from 'gvg' (flag &4) unsigned gvg_te_castle : 1; // GVG WOE:TE Castle unsigned hidemobhpbar : 1; + #ifdef ADJUST_SKILL_DAMAGE unsigned skill_damage : 1; #endif @@ -1006,6 +1009,9 @@ extern char roulette_table[32]; void do_shutdown(void); +// Addon Cell PVP [Napster] +int map_pvp_area(struct map_session_data* sd, bool flag); + #ifdef __cplusplus } #endif diff --git a/src/map/pc.c b/src/map/pc.c index 4682102bb..3342c74ce 100755 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -672,8 +672,9 @@ void pc_makesavestatus(struct map_session_data *sd) { sd->status.last_point.x = sd->bl.x; sd->status.last_point.y = sd->bl.y; } - - if(map[sd->bl.m].flag.nosave) { + + // Addon Cell PVP [Napster] + if(map[sd->bl.m].flag.nosave || map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP ) ) { struct map_data *m=&map[sd->bl.m]; if(m->save.map) memcpy(&sd->status.last_point,&m->save,sizeof(sd->status.last_point)); @@ -4826,7 +4827,7 @@ bool pc_isUseitem(struct map_session_data *sd,int n) case ITEMID_WING_OF_FLY: case ITEMID_GIANT_FLY_WING: case ITEMID_N_FLY_WING: - if( map[sd->bl.m].flag.noteleport || map_flag_gvg2(sd->bl.m) ) { + if( map[sd->bl.m].flag.noteleport || map_flag_gvg2(sd->bl.m) || map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP )) { clif_skill_teleportmessage(sd,0); return false; } @@ -4867,7 +4868,7 @@ bool pc_isUseitem(struct map_session_data *sd,int n) clif_displaymessage(sd->fd, msg_txt(sd,663)); return false; } - if( map[sd->bl.m].flag.noreturn && nameid != ITEMID_WING_OF_FLY && nameid != ITEMID_GIANT_FLY_WING && nameid != ITEMID_N_FLY_WING ) + if( map[sd->bl.m].flag.noreturn && nameid != ITEMID_WING_OF_FLY && nameid != ITEMID_GIANT_FLY_WING && nameid != ITEMID_N_FLY_WING || map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP )) return false; break; case ITEMID_MERCENARY_RED_POTION: @@ -5478,6 +5479,10 @@ enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, in } channel_pcquit(sd,4); //quit map chan + + // Addon Cell PVP [Napster] + if(sd->state.pvp && map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP)) + map[sd->state.pmap].cell_pvpuser--; } if( m < 0 ) @@ -5634,7 +5639,7 @@ bool pc_memo(struct map_session_data* sd, int pos) nullpo_ret(sd); // check mapflags - if( sd->bl.m >= 0 && (map[sd->bl.m].flag.nomemo || map[sd->bl.m].flag.nowarpto) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE) ) { + if( sd->bl.m >= 0 && (map[sd->bl.m].flag.nomemo || map[sd->bl.m].flag.nowarpto) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE) || map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP ) ) { clif_skill_teleportmessage(sd, 1); // "Saved point cannot be memorized." return false; } @@ -7528,6 +7533,12 @@ void pc_respawn(struct map_session_data* sd, clr_type clrtype) pc_setrestartvalue(sd,3); if( pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, clrtype) != SETPOS_OK ) clif_resurrection(&sd->bl, 1); //If warping fails, send a normal stand up packet. + + // Addon Cell PVP [Napster] + if (sd->state.pvp && map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP) ) + map_pvp_area(sd, 1); + else + map_pvp_area(sd, 0); } static int pc_respawn_timer(int tid, unsigned int tick, int id, intptr_t data) @@ -7542,6 +7553,55 @@ static int pc_respawn_timer(int tid, unsigned int tick, int id, intptr_t data) return 0; } +// Addon Cell PVP [Napster] +void pc_deathmatch(struct map_session_data* sd, clr_type clrtype) +{ + struct npc_data *nd; + short x = 0, y = 0; + + if( !pc_isdead(sd) ) + return; // not applicable + + if( map_getcell(sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP) && battle_config.cellpvp_deathmatch ) + { + do { + x = rand() % (map[sd->bl.m].xs - 2) + 1; + y = rand() % (map[sd->bl.m].ys - 2) + 1; + } while( !map_getcell(sd->bl.m, x, y, CELL_CHKPVP) ); + + pc_setstand(sd, true); + pc_setrestartvalue(sd,3); + status_percent_heal(&sd->bl, battle_config.deathmatch_hp_rate, battle_config.deathmatch_sp_rate); + + if( pc_setpos(sd, sd->mapindex, x, y, clrtype) ) + clif_resurrection(&sd->bl, 1); //If warping fails, send a normal stand up packet. + + status_change_clear(&sd->bl, 3); + + if(sd && battle_config.cellpvp_autobuff) + { + nd = npc_name2id("deathmatch_core"); + if (nd && nd->subtype == NPCTYPE_SCRIPT) + run_script(nd->u.scr.script, 0, sd->bl.id, nd->bl.id); + } + } +} + +static int pc_deathmatch_timer(int tid, unsigned int tick, int id, intptr_t data) +{ + struct map_session_data *sd = map_id2sd(id); + if( sd != NULL ) + { + pc_deathmatch(sd, CLR_OUTSIGHT); + if (sd->state.pvp && map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP ) ) + { + map_pvp_area(sd, 1); + map[sd->bl.m].cell_pvpuser--; + } + } + return 0; +} + /*========================================== * Invoked when a player has received damage *------------------------------------------*/ @@ -7779,7 +7839,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) } if(battle_config.bone_drop==2 - || (battle_config.bone_drop==1 && map[sd->bl.m].flag.pvp)) + || (battle_config.bone_drop==1 && map[sd->bl.m].flag.pvp) || map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP) && sd->state.pvp) { struct item item_tmp; memset(&item_tmp,0,sizeof(item_tmp)); @@ -7852,6 +7912,12 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) pc_payzeny(sd, zeny_penalty, LOG_TYPE_PICKDROP_PLAYER, NULL); } } + // Addon Cell PVP [Napster] + if (map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP ) && battle_config.cellpvp_deathmatch && sd->state.pvp) + { + add_timer(tick+battle_config.cellpvp_deathmatch_delay, pc_deathmatch_timer, sd->bl.id, 0); + return 1|8; + } if(map[sd->bl.m].flag.pvp_nightmaredrop) { // Moved this outside so it works when PVP isn't enabled and during pk mode [Ancyker] int j; @@ -10152,6 +10218,14 @@ int pc_calc_pvprank(struct map_session_data *sd) sd->pvp_rank=1; map_foreachinmap(pc_calc_pvprank_sub,sd->bl.m,BL_PC,sd); + + // Addon Cell PVP [Napster] + if( (old!=sd->pvp_rank || sd->pvp_lastusers!=m->cell_pvpuser) || sd->state.pvp ) + { + clif_pvpset( sd, sd->pvp_rank, sd->pvp_lastusers = m->cell_pvpuser, 0); + return sd->pvp_rank; + } + if(old!=sd->pvp_rank || sd->pvp_lastusers!=m->users_pvp) clif_pvpset(sd,sd->pvp_rank,sd->pvp_lastusers=m->users_pvp,0); return sd->pvp_rank; diff --git a/src/map/pc.h b/src/map/pc.h index c8be94592..f6ecdeb60 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -268,6 +268,7 @@ struct map_session_data { bool keepshop; // Whether shop data should be removed when the player disconnects bool mail_writing; // Whether the player is currently writing a mail in RODEX or not bool cashshop_open; + unsigned int pvp : 1; // Addon Cell PVP [Napster] } state; struct { unsigned char no_weapon_damage, no_magic_damage, no_misc_damage; @@ -347,6 +348,7 @@ struct map_session_data { unsigned int canskill_tick; // used to prevent abuse from no-delay ACT files unsigned int cansendmail_tick; // [Mail System Flood Protection] unsigned int ks_floodprotect_tick; // [Kill Steal Protection] + unsigned int pvpcan_walkout_tick; // Addon Cell PVP [Napster] struct s_item_delay { unsigned short nameid; diff --git a/src/map/script_constants.h b/src/map/script_constants.h index 408f3ff64..6ddb844be 100644 --- a/src/map/script_constants.h +++ b/src/map/script_constants.h @@ -448,6 +448,7 @@ export_constant(CELL_NOCHAT); export_constant(CELL_MAELSTROM); export_constant(CELL_ICEWALL); + export_constant(CELL_PVP); /* getcell types */ export_constant(CELL_CHKWALL); @@ -466,7 +467,8 @@ export_constant(CELL_CHKNOCHAT); export_constant(CELL_CHKMAELSTROM); export_constant(CELL_CHKICEWALL); - + export_constant(CELL_CHKPVP); + /* parameters */ export_parameter("StatusPoint",SP_STATUSPOINT); export_parameter("BaseLevel",SP_BASELEVEL); diff --git a/src/map/skill.c b/src/map/skill.c index 42d19eef9..789d8745f 100755 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -6976,8 +6976,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case MO_ABSORBSPIRITS: i = 0; - if (dstsd && dstsd->spiritball && (sd == dstsd || map_flag_vs(src->m) || (sd && sd->duel_group && sd->duel_group == dstsd->duel_group)) && - ((dstsd->class_&MAPID_BASEMASK) != MAPID_GUNSLINGER || (dstsd->class_&MAPID_UPPERMASK) != MAPID_REBELLION)) { // split the if for readability, and included gunslingers in the check so that their coins cannot be removed [Reddozen] + if (dstsd && dstsd->spiritball && (sd == dstsd || map_flag_vs(src->m) || (map_getcell(src->m,src->x,src->y,CELL_CHKPVP) && map_getcell(bl->m,bl->x,bl->y,CELL_CHKPVP)) || (sd && sd->duel_group && sd->duel_group == dstsd->duel_group)) && ((dstsd->class_&MAPID_BASEMASK) != MAPID_GUNSLINGER || (dstsd->class_&MAPID_UPPERMASK) != MAPID_REBELLION)) { // split the if for readability, and included gunslingers in the check so that their coins cannot be removed [Reddozen] if (dstsd->spiritball > 0) { i = dstsd->spiritball * 7; pc_delspiritball(dstsd,dstsd->spiritball,0); diff --git a/src/map/unit.c b/src/map/unit.c index ef713e1ed..879aef341 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -428,6 +428,12 @@ static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data } else sd->areanpc_id=0; pc_cell_basilica(sd); + + // Addon Cell PVP [Napster] + if( !sd->state.pvp && map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP) ) + map_pvp_area(sd, 1); + else if( sd->state.pvp && !map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP) ) + map_pvp_area(sd, 0); break; case BL_MOB: //Movement was successful, reset walktoxy_fail_count @@ -648,6 +654,28 @@ int unit_walktoxy( struct block_list *bl, short x, short y, unsigned char flag) if(!(flag&2) && (!status_bl_has_mode(bl,MD_CANMOVE) || !unit_can_move(bl))) return 0; + // Addon Cell PVP [Napster] + if (bl->type == BL_PC) + { + struct map_session_data* sd = (TBL_PC*)bl; + unsigned int tick = gettick(); + + if (sd && sd->pvpcan_walkout_tick && !map_getcell( sd->bl.m, x, y, CELL_CHKPVP ) ) { + if ( DIFF_TICK(tick, sd->pvpcan_walkout_tick) < battle_config.cellpvp_walkout_delay ) + { + int e_tick = (battle_config.cellpvp_walkout_delay - DIFF_TICK( tick, sd->pvpcan_walkout_tick))/1000; + char e_msg[150]; + if( e_tick > 99 ) + sprintf(e_msg, msg_txt(sd, 1599), sd->status.name, (double)e_tick / 60); + else + sprintf(e_msg, msg_txt(sd, 1600), sd->status.name, e_tick+1); + + clif_messagecolor(sd,color_table[COLOR_YELLOW], e_msg, false, SELF); + return 0; + } + } + } + ud->state.walk_easy = flag&1; ud->to_x = x; ud->to_y = y; @@ -959,7 +987,13 @@ bool unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, boo return false; } else sd->areanpc_id=0; - + + // Addon Cell PVP [Ize] + if( !sd->state.pvp && map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP) ) + map_pvp_area(sd, 1); + else if( sd->state.pvp && !map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP) ) + map_pvp_area(sd, 0); + if( sd->status.pet_id > 0 && sd->pd && sd->pd->pet.intimate > 0 ) { // Check if pet needs to be teleported. [Skotlex] int flag = 0; @@ -1302,6 +1336,17 @@ int unit_stop_walking(struct block_list *bl,int type) */ int unit_skilluse_id(struct block_list *src, int target_id, uint16 skill_id, uint16 skill_lv) { + // Addon Cell PVP [Napster] + struct block_list *bl = map_id2bl(target_id); + + if( bl && src->type == BL_PC && bl->type == BL_PC && src->id != target_id) + { + struct map_session_data *dstsd = (TBL_PC*)bl; + + if( dstsd && dstsd->state.pvp != ((TBL_PC*)src)->state.pvp ) + return 0; + } + return unit_skilluse_id2( src, target_id, skill_id, skill_lv, skill_castfix(src, skill_id, skill_lv),if necessary I can put my emulator on a github
this is a paid service and if you wish someone to update it for you personally, you had to negotiate with them or with the author of this mod.
-
9 hours ago, Eross said:
Hi guys ! Ive created a simple script that will dispel a player on map load. But the problem is my only plan is to dispel players who enter the portal or who uses warps (priest), so inshort it has to be a different map to trigger the dispel and not by Teleport skill.. How to make teleport skip the dispel ?? thankyou ..
OnPCLoadMapEvent: //for( set .i,0; .i < getarraysize( .Maps$ ); set .i,.i + 1 ) //if( strcharinfo(3) == .Maps$[.i] ) //sc_end sc_spirit; sc_end sc_gospel; sc_end SC_POEMBRAGI; sc_end SC_APPLEIDUN; sc_end SC_ASSNCROS; sc_end SC_WHISTLE; //sc_end 37; // holy weapon //sc_end 38; // holy armor sc_end 187; // increase all stat sc_end 194; // increase hit sc_end 196; // increase flee sc_end 198; // max hp increase sc_end 199; // max sp increase sc_end 200; // attach strength sc_end 202; // increase def sc_end 214; // SC_SCRESIST sc_end 175; // POEMBRAGI sc_end 181; // SERVICE4U //specialeffect2 235; end;try to indicate inside the txt file of the the script the loadevent mapflag. You have to put it after the script just like how we do on the other mapflags or try to set an array to blocklist some maps to your list.
ex.
prontera mapflag loadevent -
On 9/6/2021 at 9:51 PM, Froost said:
the funny thing is that you don't even need a source for this, the client already supports all of this, just add the numbers.
care to share how we can do this? as far as i know you can only use that effects on top of the player.
-
On 10/4/2020 at 9:08 AM, Sergardo said:
need at latest trrunk can someone ?
Here you go sir ^_^.
-
1
-
-
On 4/2/2021 at 9:55 PM, PaqnaN said:
hi is it posible to add demihuman resist like from thara card and magic resistance like from gtb card?
and how?
yes.
ACMD_FUNC(resist) { char output[CHAT_SIZE_MAX]; int i; struct { const char* format; int value; } output_table[] = { { " [ %d ] Neutral Resist", 0 }, { " [ %d ] Water Resist", 0 }, { " [ %d ] Earth Resist", 0 }, { " [ %d ] Fire Resist", 0 }, { " [ %d ] Wind Resist", 0 }, { " [ %d ] Poison Resist", 0 }, { " [ %d ] Holy Resist", 0 }, { " [ %d ] Dark Resist", 0 }, { " [ %d ] Ghost Resist", 0 }, { " [ %d ] Undead Resist", 0 }, ++ { " [ %d ] Long Range Resistance", 0 }, ++ { " [ %d ] Magic Resistance", 0 }, ++ { " [ %d ] Demi-Human Resist", 0 }, { NULL, 0 } }; memset(output, '\0', sizeof(output)); clif_displaymessage(sd->fd, "========= Resistance Values (in percentage) ========="); output_table[0].value = (sd->indexed_bonus.subele[ELE_NEUTRAL] + sd->indexed_bonus.subele_script[ELE_NEUTRAL] + sd->indexed_bonus.subele[ELE_ALL] + sd->indexed_bonus.subele_script[ELE_ALL]); output_table[1].value = (sd->indexed_bonus.subele[ELE_WATER] + sd->indexed_bonus.subele_script[ELE_WATER] + sd->indexed_bonus.subele[ELE_ALL] + sd->indexed_bonus.subele_script[ELE_ALL]); output_table[2].value = (sd->indexed_bonus.subele[ELE_EARTH] + sd->indexed_bonus.subele_script[ELE_EARTH] + sd->indexed_bonus.subele[ELE_ALL] + sd->indexed_bonus.subele_script[ELE_ALL]); output_table[3].value = (sd->indexed_bonus.subele[ELE_FIRE] + sd->indexed_bonus.subele_script[ELE_FIRE] + sd->indexed_bonus.subele[ELE_ALL] + sd->indexed_bonus.subele_script[ELE_ALL]); output_table[4].value = (sd->indexed_bonus.subele[ELE_WIND] + sd->indexed_bonus.subele_script[ELE_WIND]) + sd->indexed_bonus.subele[ELE_ALL] + sd->indexed_bonus.subele_script[ELE_ALL]; output_table[5].value = (sd->indexed_bonus.subele[ELE_POISON] + sd->indexed_bonus.subele_script[ELE_POISON] + sd->indexed_bonus.subele[ELE_ALL] + sd->indexed_bonus.subele_script[ELE_ALL]); output_table[6].value = (sd->indexed_bonus.subele[ELE_HOLY] + sd->indexed_bonus.subele_script[ELE_HOLY] + sd->indexed_bonus.subele[ELE_ALL] + sd->indexed_bonus.subele_script[ELE_ALL]); output_table[7].value = (sd->indexed_bonus.subele[ELE_DARK] + sd->indexed_bonus.subele_script[ELE_DARK] + sd->indexed_bonus.subele[ELE_ALL] + sd->indexed_bonus.subele_script[ELE_ALL]); output_table[8].value = (sd->indexed_bonus.subele[ELE_GHOST] + sd->indexed_bonus.subele_script[ELE_GHOST] + sd->indexed_bonus.subele[ELE_ALL] + sd->indexed_bonus.subele_script[ELE_ALL]); output_table[9].value = (sd->indexed_bonus.subele[ELE_UNDEAD] + sd->indexed_bonus.subele_script[ELE_UNDEAD] + sd->indexed_bonus.subele[ELE_ALL] + sd->indexed_bonus.subele_script[ELE_ALL]); ++ output_table[10].value = (sd->bonus.long_attack_def_rate); ++ output_table[11].value = (sd->special_state.no_magic_damage + sd->bonus.magic_def_rate); ++ output_table[12].value = (sd->subrace[RC_DEMIHUMAN]); for (i = 0; output_table.format != NULL; i++) { sprintf(output, output_table.format, output_table.value); clif_displaymessage(fd, output); } return 0; }
-
1
-
1
-
-
On 3/2/2020 at 11:42 PM, Forshaken said:
Please let me share my 3 new versions of SC_ITEMSCRIPT. SC_ITEMSCRIPT source code is already embedded on the latest emulator so i will just share my source codes for the version 2 - 4 of SC_ITEMSCRIPT. This function is very usefull in different ways but for me i used it to get an effect from an item without having the actuall item on my storage,inventory or equipment and use it as a additional buff.
SC_ITEMSCRIPT: Additional bonus effect/buff can be dispell by dispell skill and on death.
SC_ITEMSCRIPT2: Additional bonus effect/buff can be dispell by dispell skill but not on death.
SC_ITEMSCRIPT3: Additional bonus effect/buff can be dispell on dearth but not by dispell skill.
SC_ITEMSCRIPT4: Additional bonus effect/buff cannot by dispell by dispell skill nor on death.
I know it is an easy script but the idea is useful.
- script samplebuff -1,{
OnPCLoginEvent:
//sc_start sc_itemscript,<duration(- value for unlimited duration and + for limited duration)>,<itemid>;
//use SC_ITEMSCRIPT for buff dispellable by death and dispell skill
//use SC_ITEMSCRIPT2 for buff not dispellable by death but dispellable by dispell skill
//use SC_ITEMSCRIPT3 for buff not dispellable by dispell skill but dispellable by death
//use SC_ITEMSCRIPT4 for buff not dispellable by dispell skill and dispell skill
//This script use gives 10% Fire resistance from Ring of Flame lord effect permanently (it cannot be dispell by dispell skill nor on death)
SC_START SC_ITEMSCRIPT4,-1,2678;//additional effect(1000=1sec)
end;
}Ok guys here is the bug fix for dispel mechanics.
-
@Mabuhay . I was able to update this src but there is some kind of memory leak issue after updating it.
Hi Guys! I manage to update the src but there is a memory leak issue after updating and fixing it is out of my skills. Use it at your own risk. Please do share your src if you manage to fix the memory leak issue.
-
Up for this. OnPCStatCalcEvent has been removed from the latest git.
-
On 12/29/2020 at 5:16 AM, tonn said:
I'm encountering the same issue. Does anyone know how to debug this, at least?
Im having the same issue.
I have fixed the problem. so far there is no disconnection issue. add this codes on your PC.CPP
struct map_session_data {
struct block_list bl;
struct unit_data ud;
struct view_data vd;
struct status_data base_status, battle_status;
struct status_change sc;
struct regen_data regen;
struct regen_data_sub sregen, ssregen;
++struct autoattack_delay; // autoattack timer
//NOTE: When deciding to add a flag to state or special_state, take into consideration that state is preserved in
//status_calc_pc, while special_state is recalculated in each call. [Skotlex]
struct s_state {
unsigned int active : 1; //Marks active player (not active is logging in/out, or changing map servers)
unsigned int menu_or_input : 1;// if a script is waiting for feedback from the player
unsigned int dead_sit : 2;
unsigned int lr_flag : 3;//1: left h. weapon; 2: arrow
-------------------------------------------------------------------------------------------------
unsigned int lesseffect : 1;
unsigned int vending : 1;
unsigned int noks : 3; // [Zeph Kill Steal Protection]
++unsigned autoattack : 1; // Keitenai
unsigned int changemap : 1;
unsigned int callshop : 1; // flag to indicate that a script used callshop; on a shop
-------------------------------------------------------------------------------------------------
int invincible_timer;
t_tick canlog_tick;
t_tick canuseitem_tick; // [Skotlex]
t_tick canusecashfood_tick;
t_tick canequip_tick; // [Inkfish]
t_tick cantalk_tick;
t_tick canskill_tick; // used to prevent abuse from no-delay ACT files
t_tick cansendmail_tick; // [Mail System Flood Protection]
t_tick ks_floodprotect_tick; // [Kill Steal Protection]
++t_tick autoattack_delay; // Keitenai
t_tick equipswitch_tick; // Equip switch -
@sader1992
This will also solve the compatibility for 2015 + clients right???? -
On 2/12/2020 at 12:45 AM, Functor said:
Correct
error still persist even thou the players ram is 8gb and we only run 1 client
-
17 hours ago, fusqueta said:
It's a good altenative, but I'm planning to add item script further on this, a flag disabling unequip would be perfect
you can make your own mapflag script and dig deeper on your itemdb.cpp
-
1 hour ago, fusqueta said:
is there anyway to prevent to unequip a single item? I'll bind a visual effect to the item sprite and player cannot unequip it
ps: I'm planning to execute a UnEquipScript to equip item again, but seems like a poor way to solve this problem, another better idea?
why not use OnPCLoginEvent and use changelook script?
-
2
-
-
UP FOR THIS ISSUE
-
Good day everyone! I just wanted to ask if how to fix elemental resist healing on woe/gvg?
Elemental resist healing is where if your resistance exceeds to 100% on a certain element, that element will heal you when you take damage on it.
ex. If you got 110% Wind resist and you got hit by Lightning bolt or anything that is wind element will heal you instead of taking damage.
My current situation is it works on PvP but not on GvG. Please help!!!




Warp npc with tiers
in Script Requests
Posted
You can use the OnTouch event script then just disable it upon defeating the monster on the first map then enable the next OnTouch event script going to the next map.