-
Posts
1678 -
Joined
-
Last visited
-
Days Won
71
Content Type
Profiles
Forums
Downloads
Jobs Available
Server Database
Third-Party Services
Top Guides
Store
Crowdfunding
Posts posted by sader1992
-
-
8 hours ago, worn said:
can i use this in several maps the second example? or is there any problem? example I'll create one just for lhz, another just for pay_dun another just for x map
- script monsterdrop -1,{ OnNPCKillEvent: if(inarray(.maps$,strcharinfo(3)) != -1){ if(rand(100) <= 9){//9% getitem(502,1);//item id is the 502 } } end; OnInit: setarray .maps$,"lhz_dun03","prontera"; end; }
-
5 hours ago, DevilSupremeRO said:
Reward Giver for Group ID 1 Thanks in advance
not much information given
something like this ?
if(getgroupid() == 1){ if(!GotTheReward){ getitem(501,1); GotTheReward = true; mes "you got the reward"; end; }else{ mes "you already got the reward"; end; } }else{ mes"this reward only for group id 1"; end; }
-
all monsters
- script monsterdrop -1,{ OnNPCKillEvent: if(rand(100) <= 9){//9% getitem(502,1);//item id is the 502 } end; }
only in lhz_dun03
- script monsterdrop -1,{ OnNPCKillEvent: if(strcharinfo(3) == "lhz_dun03"){//map name lhz_dun03 if(rand(100) <= 9){//9% getitem(502,1);//item id is the 502 } } end; }
- 1
-
8 hours ago, kalabasa said:
//===== rAthena Script ======================================= //= Disguise Event //===== By: ================================================== //= GmOcean //===== Current Version: ===================================== //= 5.1 //===== Compatible With: ===================================== //= rAthena Project //===== Description: ========================================= //= Guess a monster name correctly for prizes. //= //= NOTE: Requires PCRE library installed. //===== Additional Comments: ================================= //= 5.0 Last update by GmOcean. //= 5.1 Cleaned and standardized, mostly. [Euphy] //============================================================ prontera,160,155,4 script Disguise Event 795,{ // Currently set to run every two hours. // To change times, edit the OnClock labels below. set .@GMLevel,60; // GM level required to access NPC. set .@n$,"[^0000FFDisguise NPC^000000]"; if (getgmlevel()>=.@GMLevel) { mes .@n$; mes "Select an option."; next; switch(select("Turn ON/OFF Event:Event Settings")) { case 1: mes .@n$; if (.EventON) { mes "The Event is currently: [^0000FFON^000000]"; mes "Would you like to turn it OFF?"; } else { mes "The Event is currently: [^FF0000OFF^000000]"; mes "Would you like to turn it ON?"; } if(select("Yes:No")==2) close; if (.EventON) { set .EventON,0; set .Timer,0; setnpctimer 0; stopnpctimer; announce "A GM has decided to turn the Disguise Event off. As a result no further prizes will be given.",bc_map | bc_blue; deletepset 1; setnpcdisplay "Disguise Event",795; close; } set .EventON,1; set .Timer,1; setnpctimer 0; initnpctimer; set .ResetCounter,.ResetCounter+1; announce "The Disguise Event will begin in 3 minutes.",bc_all | bc_blue; announce "The Event is being held in Prontera.",bc_all | bc_blue; close; case 2: mes .@n$; mes "Pick a setting to modify."; next; switch(select("Monster Display:Number of Rounds:Prize Settings")) { case 1: setarray .@r$[0],"Disguise as all monsters.","Disguise as MVPs only."; mes .@n$; mes "Choose a disguise rule."; next; set .Rule, select(implode(.@r$,":")); mes .@n$; mes "The Disguise Rule has been set:"; mes " > ^0055FF"+.@r$[.Rule-1]+"^000000"; close; case 2: mes .@n$; mes "Input the number of rounds you want the event to last."; mes "Current number: [^0000FF"+.Rounds+"^000000]"; next; input .@Rounds; set .Rounds,.@Rounds; mes .@n$; mes "The number of rounds has been changed to "+.Rounds+"."; close; case 3: mes .@n$; mes "Input the Item ID of the prize given each round."; mes "Current item: [^0000FF"+getitemname(.Prize)+"^000000] (ID #"+.Prize+")"; next; input .@Prize; mes .@n$; if (getitemname(.@Prize)=="" || getitemname(.@Prize)=="null") { mes "That item does not exist. Please try again."; close; } set .Prize,.@Prize; mes "Input the amount to be given."; next; input .@amount; mes .@n$; if (.@amount<=0 || .@amount>=10000) { mes "That amount is invalid. Using default amount of 1."; set .@amount,1; next; mes .@n$; } set .PrizeAmt,.@amount; mes "The Prize has been changed successfully."; mes "Prize: "+.PrizeAmt+"x [^0000FF"+getitemname(.Prize)+"^000000]"; close; } } } if (.EventON) end; mes .@n$; mes "Welcome."; mes "How may I be of assistance?"; if(select("Information:Nothing, just passing through.")==2) close; next; mes .@n$; mes "This event is quite simple."; mes "At the start of the event, I will"; mes "disguise myself as a random"; mes "monster. You have to shout"; mes "that monster's name out loud."; next; mes "If you are correct, you will receive"; mes "a prize. If not, keep trying!"; mes "That's all that there is to this event."; close; OnInit: set .EventON,0; set .Wait,0; set .Winner,0; set .ResetCounter,0; set .Rounds,10; set .Prize,512; set .PrizeAmt,1; set .Rule,1; setarray .MVP[0],1038,1039,1046,1059,1086,1087,1112,1115,1147,1150,1157,1159,1190,1251,1252,1272,1312,1373, 1389,1399,1418,1492,1502,1511,1583,1623,1630,1646,1647,1648,1649,1650,1651,1658,1685,1688, 1708,1719,1734,1751,1768,1779,1785,1802,1832,1871,1874,1885,1917,1980,2022,2068,2087,2131, 2156,2165; set .BlackList$, "1003,1006,1017,1021,1022,1027,1043,1075,1136,1137,1168," + "1171,1172,1173,1181,1187,1210,1217,1218,1222,1223,1224,1225,1226,1227,1228," + "1233,1284,1407,1411,1414,1495,1501,1900,1996,2000,2001,2002,2003,2004," + "2005,2006,2007,2011,2012,2025,2028,2029,2030,2031,2032,2033,2034,2035," + "2036,2037,2038,2039,2040,2041,2042,2043,2044,2045,2046,2047,2048,2049," + "2050,2051,2052,2053,2054,2055,2056,2057,2058,2059,2060,2061,2062,2063," + "2064,2065,2066,2067,2075,2076,2077,2078,2079,2080,2081,2083,2084,2085," + "2086,2087,2088,2089,2090,2091,2092,2093,2094,2095,2096,2097,2098,2099," + "2100,2101,2012,2103,2104,2105,2106,2107,2108,2109,2110,2111,2112,2113," + "2114,2115,2116,2117,2118,2119,2120,2121,2123,2124,2125,1496,"; end; OnClock0000: OnClock0200: OnClock0400: OnClock0600: OnClock0800: OnClock1000: OnClock1200: OnClock1400: OnClock1600: OnClock1800: OnClock2000: OnClock2200: set .ResetCounter,.ResetCounter+1; set .EventON,1; set .Timer,1; set .Wait,1; announce "The Disguise Event will begin in 3 minutes.",bc_all | bc_blue; announce "The Event is being held in Prontera.",bc_all | bc_blue; setnpctimer 0; initnpctimer; end; OnTimer10000: if (.Timer || .Change) end; set .Wait,0; goto iDisguise; end; OnTimer30000: if (.Timer) end; set .Change,0; setnpcdisplay "Disguise Event",795; npctalk "Disguise Event : You took too long to guess what I was. Please wait 10 seconds while I disguise again."; specialeffect EF_DETECT2; set $MonsterName$,""; deletepset 1; stopnpctimer; setnpctimer 0; initnpctimer; end; OnTimer60000: if (.Timer!=1) end; announce "The Disguise Event will begin in 2 minutes.",bc_all | bc_blue; announce "The Event is being held in Prontera.",bc_all | bc_blue; end; OnTimer120000: if (.Timer!=1) end; announce "The Disguise Event will begin 1 minute.",bc_all | bc_blue; announce "The Event is being held in Prontera.",bc_all | bc_blue; end; OnTimer180000: if (.Timer!=1) end; announce "The Disguise Event has begun!",bc_all | bc_blue; announce "The Event is being held in Prontera.",bc_all | bc_blue; set .Timer,0; stopnpctimer; setnpctimer 0; initnpctimer; iDisguise: if (.Rule==1) { set .Winner,0; set .Monster,1000+rand(1,995); if (compare(","+.BlackList$+"," , ","+.Monster+",")) goto iDisguise; if (.Monster==.LastMonster) goto iDisguise; set .LastMonster,.Monster; set $MonsterName$,getmonsterinfo(.Monster,0); } if (.Rule==2) { set .Winner,0; set .Monster,rand(49); set $MonsterName$,getmonsterinfo(.MVP[.Monster],0); } deletepset 1; defpattern 1,"([^:]+):.\\s*"+$MonsterName$+".*", "iCorrect"; activatepset 1; if (.Rule==1) setnpcdisplay "Disguise Event",.Monster; if (.Rule==2) setnpcdisplay "Disguise Event",.MVP[.Monster]; set .Change,1; setnpctimer 0; end; iCorrect: if (.Winner) { dispbottom "Someone has already won this round."; end; } set .Winner,1; set .RoundCount,.RoundCount+1; deletepset 1; activatepset 1; getitem .Prize,.PrizeAmt; announce strcharinfo(0)+" is correct! I was disguised as: "+$MonsterName$+"",bc_map | bc_blue; if (.RoundCount>=.Rounds) { setnpcdisplay "Disguise Event",795; set .RoundCount,0; set .Change,0; set .EventON,0; setnpctimer 0; stopnpctimer; npctalk "Disguise Event : Thank you all for playing. That was the last round of the Disguise Event. Come play again later."; end; } setnpcdisplay "Disguise Event",795; set .Change,0; setnpctimer 0; end; }
this is the code i want to insert
// setarray .@reward1, "chance", item id, item amount... setarray .@reward1, 5, 7539, 10; // Item ID 7539 x 10with chance of 5% in getting, You can add more.. setarray .@reward2, 15, 7420, 5; // Item ID 7420 x 5 with chance of 15% in getting, You can add more.. setarray .@reward3, 20, 671, 1; // etc... setarray .@reward4, 25, 672, 1; setarray .@reward5, 30, 673, 1; setarray .@reward7, 100, 673, 1; sleep2 300; set .@r, rand(100); while( .@r >= getd( ".@reward"+ .@i ) ) .@i++; .@rand_index = rand( 1,( getarraysize( getd( ".@reward"+ .@i ) ) -1 )/2 ) *2 -1; getitem getd( ".@reward"+ .@i +"["+ .@rand_index +"]" ), getd( ".@reward"+ .@i +"["+ (.@rand_index +1) +"]" );
did you really just edited your old reply to give me what i asked for next? and by doing that you made it so i don't get a notification and you were waiting for my reply ?
//===== rAthena Script ======================================= //= Disguise Event //===== By: ================================================== //= GmOcean //===== Current Version: ===================================== //= 5.1 //===== Compatible With: ===================================== //= rAthena Project //===== Description: ========================================= //= Guess a monster name correctly for prizes. //= //= NOTE: Requires PCRE library installed. //===== Additional Comments: ================================= //= 5.0 Last update by GmOcean. //= 5.1 Cleaned and standardized, mostly. [Euphy] //============================================================ prontera,160,155,4 script Disguise Event 795,{ // Currently set to run every two hours. // To change times, edit the OnClock labels below. set .@GMLevel,60; // GM level required to access NPC. set .@n$,"[^0000FFDisguise NPC^000000]"; if (getgmlevel()>=.@GMLevel) { mes .@n$; mes "Select an option."; next; switch(select("Turn ON/OFF Event:Event Settings")) { case 1: mes .@n$; if (.EventON) { mes "The Event is currently: [^0000FFON^000000]"; mes "Would you like to turn it OFF?"; } else { mes "The Event is currently: [^FF0000OFF^000000]"; mes "Would you like to turn it ON?"; } if(select("Yes:No")==2) close; if (.EventON) { set .EventON,0; set .Timer,0; setnpctimer 0; stopnpctimer; announce "A GM has decided to turn the Disguise Event off. As a result no further prizes will be given.",bc_map | bc_blue; deletepset 1; setnpcdisplay "Disguise Event",795; close; } set .EventON,1; set .Timer,1; setnpctimer 0; initnpctimer; set .ResetCounter,.ResetCounter+1; announce "The Disguise Event will begin in 3 minutes.",bc_all | bc_blue; announce "The Event is being held in Prontera.",bc_all | bc_blue; close; case 2: mes .@n$; mes "Pick a setting to modify."; next; switch(select("Monster Display:Number of Rounds:Prize Settings")) { case 1: setarray .@r$[0],"Disguise as all monsters.","Disguise as MVPs only."; mes .@n$; mes "Choose a disguise rule."; next; set .Rule, select(implode(.@r$,":")); mes .@n$; mes "The Disguise Rule has been set:"; mes " > ^0055FF"+.@r$[.Rule-1]+"^000000"; close; case 2: mes .@n$; mes "Input the number of rounds you want the event to last."; mes "Current number: [^0000FF"+.Rounds+"^000000]"; next; input .@Rounds; set .Rounds,.@Rounds; mes .@n$; mes "The number of rounds has been changed to "+.Rounds+"."; close; case 3: mes .@n$; mes "Input the Item ID of the prize given each round."; mes "Current item: [^0000FF"+getitemname(.Prize)+"^000000] (ID #"+.Prize+")"; next; input .@Prize; mes .@n$; if (getitemname(.@Prize)=="" || getitemname(.@Prize)=="null") { mes "That item does not exist. Please try again."; close; } set .Prize,.@Prize; mes "Input the amount to be given."; next; input .@amount; mes .@n$; if (.@amount<=0 || .@amount>=10000) { mes "That amount is invalid. Using default amount of 1."; set .@amount,1; next; mes .@n$; } set .PrizeAmt,.@amount; mes "The Prize has been changed successfully."; mes "Prize: "+.PrizeAmt+"x [^0000FF"+getitemname(.Prize)+"^000000]"; close; } } } if (.EventON) end; mes .@n$; mes "Welcome."; mes "How may I be of assistance?"; if(select("Information:Nothing, just passing through.")==2) close; next; mes .@n$; mes "This event is quite simple."; mes "At the start of the event, I will"; mes "disguise myself as a random"; mes "monster. You have to shout"; mes "that monster's name out loud."; next; mes "If you are correct, you will receive"; mes "a prize. If not, keep trying!"; mes "That's all that there is to this event."; close; OnInit: // setarray .@reward1, "chance", item id, item amount... setarray .reward1, 5, 7539, 10; // Item ID 7539 x 10with chance of 5% in getting, You can add more.. setarray .reward2, 15, 7420, 5; // Item ID 7420 x 5 with chance of 15% in getting, You can add more.. setarray .reward3, 20, 671, 1; // etc... setarray .reward4, 25, 672, 1; setarray .reward5, 30, 673, 1; setarray .reward7, 100, 673, 1; set .EventON,0; set .Wait,0; set .Winner,0; set .ResetCounter,0; set .Rounds,10; set .Prize,512; set .PrizeAmt,1; set .Rule,1; setarray .MVP[0],1038,1039,1046,1059,1086,1087,1112,1115,1147,1150,1157,1159,1190,1251,1252,1272,1312,1373, 1389,1399,1418,1492,1502,1511,1583,1623,1630,1646,1647,1648,1649,1650,1651,1658,1685,1688, 1708,1719,1734,1751,1768,1779,1785,1802,1832,1871,1874,1885,1917,1980,2022,2068,2087,2131, 2156,2165; set .BlackList$, "1003,1006,1017,1021,1022,1027,1043,1075,1136,1137,1168," + "1171,1172,1173,1181,1187,1210,1217,1218,1222,1223,1224,1225,1226,1227,1228," + "1233,1284,1407,1411,1414,1495,1501,1900,1996,2000,2001,2002,2003,2004," + "2005,2006,2007,2011,2012,2025,2028,2029,2030,2031,2032,2033,2034,2035," + "2036,2037,2038,2039,2040,2041,2042,2043,2044,2045,2046,2047,2048,2049," + "2050,2051,2052,2053,2054,2055,2056,2057,2058,2059,2060,2061,2062,2063," + "2064,2065,2066,2067,2075,2076,2077,2078,2079,2080,2081,2083,2084,2085," + "2086,2087,2088,2089,2090,2091,2092,2093,2094,2095,2096,2097,2098,2099," + "2100,2101,2012,2103,2104,2105,2106,2107,2108,2109,2110,2111,2112,2113," + "2114,2115,2116,2117,2118,2119,2120,2121,2123,2124,2125,1496,"; end; OnClock0000: OnClock0200: OnClock0400: OnClock0600: OnClock0800: OnClock1000: OnClock1200: OnClock1400: OnClock1600: OnClock1800: OnClock2000: OnClock2200: set .ResetCounter,.ResetCounter+1; set .EventON,1; set .Timer,1; set .Wait,1; announce "The Disguise Event will begin in 3 minutes.",bc_all | bc_blue; announce "The Event is being held in Prontera.",bc_all | bc_blue; setnpctimer 0; initnpctimer; end; OnTimer10000: if (.Timer || .Change) end; set .Wait,0; goto iDisguise; end; OnTimer30000: if (.Timer) end; set .Change,0; setnpcdisplay "Disguise Event",795; npctalk "Disguise Event : You took too long to guess what I was. Please wait 10 seconds while I disguise again."; specialeffect EF_DETECT2; set $MonsterName$,""; deletepset 1; stopnpctimer; setnpctimer 0; initnpctimer; end; OnTimer60000: if (.Timer!=1) end; announce "The Disguise Event will begin in 2 minutes.",bc_all | bc_blue; announce "The Event is being held in Prontera.",bc_all | bc_blue; end; OnTimer120000: if (.Timer!=1) end; announce "The Disguise Event will begin 1 minute.",bc_all | bc_blue; announce "The Event is being held in Prontera.",bc_all | bc_blue; end; OnTimer180000: if (.Timer!=1) end; announce "The Disguise Event has begun!",bc_all | bc_blue; announce "The Event is being held in Prontera.",bc_all | bc_blue; set .Timer,0; stopnpctimer; setnpctimer 0; initnpctimer; iDisguise: if (.Rule==1) { set .Winner,0; set .Monster,1000+rand(1,995); if (compare(","+.BlackList$+"," , ","+.Monster+",")) goto iDisguise; if (.Monster==.LastMonster) goto iDisguise; set .LastMonster,.Monster; set $MonsterName$,getmonsterinfo(.Monster,0); } if (.Rule==2) { set .Winner,0; set .Monster,rand(49); set $MonsterName$,getmonsterinfo(.MVP[.Monster],0); } deletepset 1; defpattern 1,"([^:]+):.\\s*"+$MonsterName$+".*", "iCorrect"; activatepset 1; if (.Rule==1) setnpcdisplay "Disguise Event",.Monster; if (.Rule==2) setnpcdisplay "Disguise Event",.MVP[.Monster]; set .Change,1; setnpctimer 0; end; iCorrect: if (.Winner) { dispbottom "Someone has already won this round."; end; } set .Winner,1; set .RoundCount,.RoundCount+1; deletepset 1; activatepset 1; set .@r, rand(100); while( .@r >= getd( ".reward"+ .@i ) ) .@i++; .@rand_index = rand( 1,( getarraysize( getd( ".reward"+ .@i ) ) -1 )/2 ) *2 -1; getitem getd( ".reward"+ .@i +"["+ .@rand_index +"]" ), getd( ".reward"+ .@i +"["+ (.@rand_index +1) +"]" ); getitem .Prize,.PrizeAmt; announce strcharinfo(0)+" is correct! I was disguised as: "+$MonsterName$+"",bc_map | bc_blue; if (.RoundCount>=.Rounds) { setnpcdisplay "Disguise Event",795; set .RoundCount,0; set .Change,0; set .EventON,0; setnpctimer 0; stopnpctimer; npctalk "Disguise Event : Thank you all for playing. That was the last round of the Disguise Event. Come play again later."; end; } setnpcdisplay "Disguise Event",795; set .Change,0; setnpctimer 0; end; }
- 2
-
I see now the script is edited more , and the error should now change like you wont get the "getitem" error
putting the code like that it wont work , put it all of it in the same place where the player will get the reward.
provide the unedited script and the code you want to import separately and where the reward line would be and i will put it for you
-
if you get that kind of error , most likely the problem is before the code you posted.
post the full code!
-
"make_listen_bind: bind failed" means that the port is already in-use , maybe you have another copy of the program already running , or you use the port for something else already
if you don't use the port for something else , i think the most non-technical way for you to fix is to reboot your system , the first time you run the program again after the reboot should work , if it didn't work the 2nd time and after that then you are not closing the program , you are just hiding it
for Windows check the task manager , for Linux search for a task manager in the internet , I recommend "htop", search for the program and end it task
you should also learn how to open/close programs properly.
ofc that doesn't mean you wont get other errors , this only for how to fix the "make_listen_bind: bind failed" error
-
On 12/18/2021 at 9:02 PM, doctrine said:
this is outdated. are there any new ways?
import the file to grf editor , and export it from there.
-
setarray .blackList[0],0; //Array of black listed item ID
- 1
-
you need to check your iteminfo file , the one you are using , not just use whatever it work , open the iteminfo file as text and search for the item id and make sure the item files are correct, you can find the item files in your grf or data folder
check here to understand how the iteminfo works
https://github.com/rathena/rathena/wiki/Custom-Items#systemiteminfolub
-
i think this should work
OnPCLogoutEvent: setlook LOOK_BODY2,false; end;
-
I think you can simply just edit this
https://github.com/rathena/rathena/blob/master/db/item_randomopt_db.yml
just remove the mode line "Mode: Renewal"
- 2
-
17 hours ago, qtdan said:
yeah it stops when i already exchange more than 50, the problem is if i change 1st time of the day by 49 i records 49 and again if i change again 50 total of 99 it still accepts it.
I didn't understand but I guess you are talking about the .@left
look how I used it in the example above, you assigned it in your script but you never used it
-
this is a reference for you
if(getd("#wqeqwe_" + gettime(DT_YYYYMMDD)) < .day_limit){ .@left = .day_limit - getd("#wqeqwe_" + gettime(DT_YYYYMMDD)); mes "Input how many"; input .@count,0,.@left; delitem .@coin,.@count; getitem .@new_coin,.@count; setd("#wqeqwe_" + gettime(DT_YYYYMMDD),getd("#wqeqwe_" + gettime(DT_YYYYMMDD)) + .@count); end; } mes "You cannot exchange anymore today!"; end;
-
for(.@i=0;.@i<getarraysize(.@vtemp);.@i++){
to
for(.@i=0;.@i<getarraysize(.@result_value);.@i++){
- 1
-
23 hours ago, mhielo12 said:
Updated for latest git.
diff --git a/conf/battle/battle.conf b/conf/battle/battle.conf index 93fe9db..0e741ad 100644 --- a/conf/battle/battle.conf +++ b/conf/battle/battle.conf @@ -167,3 +167,6 @@ warg_can_falcon: no // Should the target be able of dodging damage by snapping away to the edge of the screen? // Official behavior is "no" snap_dodge: no + +// Reserved Char ID for costume converted items. +reserved_costume_id: 999998 diff --git a/npc/custom/etc/costume.txt b/npc/custom/etc/costume.txt new file mode 100644 index 0000000..bf3772c --- /dev/null +++ b/npc/custom/etc/costume.txt @@ -0,0 +1,135 @@ +// ------------------------------------------------------------------------------- +// Script Name : Headgear to Costume converter >> Costume to Headgear converter +// ------------------------------------------------------------------------------- +// Description : +// - Allows a user to convert the equipped headgear (on Top, Mid or Low) into a +// costume item. It will remove any card and refine of the Item. +// - Allows a user to restore the equipped costume headgear (on Top, Mid or Low) +// into its original form. It will not return any card or refine of the item. +// ------------------------------------------------------------------------------- +function script costume { + .@npc_name$ = getarg(0); + disable_items; + mes "["+ .@npc_name$ +"]"; + mes "Here you can convert your headgears into a Costume Headgear or restore to its Original form."; + next; + + switch(select("I want to convert.:I want to restore.:No thanks.")) { + case 1: + setarray .@indices[1], EQI_HEAD_TOP, EQI_HEAD_MID, EQI_HEAD_LOW; + for (.@i = 1; .@i<=3; ++.@i) { + if (getequipisequiped(.@indices[.@i])) { + .@menu$ = .@menu$ + F_getpositionname(.@indices[.@i]) + "-[" + getequipname(.@indices[.@i]) + "]"; + .@equipped = 1; + } + .@menu$ = .@menu$ + ":"; + } + + if (.@equipped == 0) { + mes "["+ .@npc_name$ +"]"; + mes "You need to wear headgears that I can costume..."; + close; + } + + mes "["+ .@npc_name$ +"]"; + mes "Please select what to convert."; + mes "Remember, cards and refine will be removed."; + next; + + .@part = .@indices[ select(.@menu$) ]; + if (!getequipisequiped(.@part)) { + mes "["+ .@npc_name$ +"]"; + mes "You're not wearing anything there..."; + close; + } + + mes "["+ .@npc_name$ +"]"; + mes "You want to Costume your " + getitemname(getequipid(.@part)) + "?"; + next; + + if (select("Yes, proceed:No, sorry.") == 2) { + mes "["+ .@npc_name$ + "]"; + mes "Need some time to think about it, huh?"; + mes "Alright, I can understand."; + close; + } + + costume .@part; // Convert the Headgear + + mes "["+ .@npc_name$ +"]"; + mes "Done, enjoy your costume headgear."; + close; + case 2: + setarray .@indices[1], EQI_COSTUME_HEAD_TOP, EQI_COSTUME_HEAD_MID, EQI_COSTUME_HEAD_LOW; + for (.@i = 1; .@i<=3; ++.@i) { + if (getequipisequiped(.@indices[.@i])) { + .@menu$ = .@menu$ + F_getpositionname(.@indices$[.@i]) + "-[" + getequipname(.@indices[.@i]) + "]"; + .@equipped = 1; + } + .@menu$ = .@menu$ + ":"; + } + + if (.@equipped == 0) { + mes "["+ .@npc_name$ +"]"; + mes "You need to wear costumed headgears that I can restore..."; + close; + } + + mes "["+ .@npc_name$ +"]"; + mes "Please select what to restore."; + mes "Remember, I will only restore it back without refine and cards."; + next; + + .@part = .@indices[ select(.@menu$) ]; + if (!getequipisequiped(.@part)) { + mes "["+ .@npc_name$ +"]"; + mes "You're not wearing anything there..."; + close; + } + + if (isequippedcnt(getequipid(.@part)) > 1) { + mes "["+ .@npc_name$ +"]"; + mes "You're wearing too many of the same headgear!"; + mes "How am I supposed to know which one to restore?"; + mes "See me when you have one equipped."; + close; + } + + if (countitem(getequipid(.@part)) > 1) { + mes "["+ .@npc_name$ +"]"; + mes "You have another " + getitemname(getequipid(.@part)) + " with you."; + mes "Put it away before restoring."; + close; + } + + mes "[" + .@npc_name$ + "]"; + mes "You want to restore your " + getitemname(getequipid(.@part)) + "?"; + next; + + if (select("Yes, proceed:No, sorry.") == 2) { + mes "["+ .@npc_name$ +"]"; + mes "Need some time to think about it, huh?"; + mes "Alright, I can understand."; + close; + } + + // Restore headgear by recreating + a = getequipid(.@part); + delitem a,1; + getitem a,1; + + mes "["+ .@npc_name$ +"]"; + mes "Done, enjoy your restored headgear."; + close; + case 3: + mes "["+ .@npc_name$ +"]"; + mes "Very well. Return at once if you seek my services."; + close; + } +} + +// --------------------------------------------------------------------------- +// Add more lines to put your npc on different cities (adjust name if desired) +// --------------------------------------------------------------------------- +prontera,144,230,6 script Costume Clown#1 715,{ callfunc "costume","Costume Clown",0; end; } + diff --git a/npc/scripts_custom.conf b/npc/scripts_custom.conf index 1adf1f3..d4e5706 100644 --- a/npc/scripts_custom.conf +++ b/npc/scripts_custom.conf @@ -115,6 +115,8 @@ npc: npc/custom/etc/quest_warper.txt // -- Custom quests from official Umbalian Quests //npc: npc/custom/quests/sphinx_mask.txt //npc: npc/custom/quests/umbalian_language.txt +// -- Costume NPC script (from rAthena) +npc: npc/custom/etc/costume.txt // --------------------- ChocobotRO Scripts -------------------- // -- Peak NPC script (from FluxCP) diff --git a/src/custom/atcommand_def.inc b/src/custom/atcommand_def.inc index 54d9e74..d9b8b2d 100644 --- a/src/custom/atcommand_def.inc +++ b/src/custom/atcommand_def.inc @@ -9,3 +9,6 @@ **/ //ACMD_DEF(newcommand), + +// @costumeitem <item> +ACMD_DEF2("costumeitem", item), diff --git a/src/custom/script.inc b/src/custom/script.inc index 839b990..776120e 100644 --- a/src/custom/script.inc +++ b/src/custom/script.inc @@ -17,3 +17,44 @@ // script_pushint(st,1); // return 0; //} + +/*========================================== + * Costume Items + *------------------------------------------*/ +BUILDIN_FUNC(costume) +{ + int i = -1, num, ep; + TBL_PC *sd; + item* item; + num = script_getnum(st, 2); // Equip Slot + if (!script_rid2sd(sd)) + return 0; + if (equip_index_check(num)) + i = pc_checkequip(sd, equip_bitmask[num]); + if (i < 0) + return 0; + item = &sd->inventory.u.items_inventory[i]; + ep = item->equip; + if (!(ep&EQP_HEAD_LOW) && !(ep&EQP_HEAD_MID) && !(ep&EQP_HEAD_TOP)) + return 0; + log_pick_pc(sd, LOG_TYPE_SCRIPT, -1, item); + pc_unequipitem(sd, i, 2); + clif_delitem(sd, i, 1, 3); + // -------------------------------------------------------------------- + item->refine = 0; + item->attribute = 0; + item->card[0] = CARD0_CREATE; + item->card[1] = 0; + item->card[2] = GetWord(battle_config.reserved_costume_id, 0); + item->card[3] = GetWord(battle_config.reserved_costume_id, 1); + if (ep&EQP_HEAD_TOP) { ep &= ~EQP_HEAD_TOP; ep |= EQP_COSTUME_HEAD_TOP; } + if (ep&EQP_HEAD_LOW) { ep &= ~EQP_HEAD_LOW; ep |= EQP_COSTUME_HEAD_LOW; } + if (ep&EQP_HEAD_MID) { ep &= ~EQP_HEAD_MID; ep |= EQP_COSTUME_HEAD_MID; } + // -------------------------------------------------------------------- + log_pick_pc(sd, LOG_TYPE_SCRIPT, 1, item); + clif_additem(sd, i, 1, 0); + pc_equipitem(sd, i, ep); + clif_misceffect(&sd->bl, 3); + return 0; +} + diff --git a/src/custom/script_def.inc b/src/custom/script_def.inc index 8863992..917ffea 100644 --- a/src/custom/script_def.inc +++ b/src/custom/script_def.inc @@ -9,3 +9,6 @@ **/ //BUILDIN_DEF(example,""), + +// Costume System +BUILDIN_DEF(costume,"i"), diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp index 266f375..8e9f8af 100644 --- a/src/map/atcommand.cpp +++ b/src/map/atcommand.cpp @@ -1343,7 +1343,7 @@ static void warp_get_suggestions(struct map_session_data* sd, const char *name) ACMD_FUNC(item) { char item_name[100]; - int number = 0, bound = BOUND_NONE; + int number = 0, bound = BOUND_NONE, costume = 0; char flag = 0; struct item item_tmp; struct item_data *item_data[10]; @@ -1382,6 +1382,26 @@ static void warp_get_suggestions(struct map_session_data* sd, const char *name) clif_displaymessage(fd, msg_txt(sd,19)); // Invalid item ID or name. return -1; } + + // Start costume conversion logic (1) + if(!strcmpi(command+1, "costumeitem")) { + if(!battle_config.reserved_costume_id) { + clif_displaymessage(fd, "Costume conversion is disabled. Set a value for reserved_costume_id in your battle.conf file."); + return -1; + } + if(!(item.get()->equip&EQP_HEAD_LOW) && + !(item.get()->equip&EQP_HEAD_MID) && + !(item.get()->equip&EQP_HEAD_TOP) && + !(item.get()->equip&EQP_COSTUME_HEAD_LOW) && + !(item.get()->equip&EQP_COSTUME_HEAD_MID) && + !(item.get()->equip&EQP_COSTUME_HEAD_TOP)) { + clif_displaymessage(fd, "You cannot costume this item. Costumes only work for headgears."); + return -1; + } + costume = 1; + + } + // End costume conversion logic (1) + itemlist = strtok(NULL, ":"); //next itemline j++; } @@ -1403,6 +1423,15 @@ static void warp_get_suggestions(struct map_session_data* sd, const char *name) item_tmp.nameid = item_id; item_tmp.identify = 1; item_tmp.bound = bound; + + // Start costume conversion logic (2) + if(costume == 1) { + item_tmp.card[0] = CARD0_CREATE; + item_tmp.card[2] = GetWord(battle_config.reserved_costume_id, 0); + item_tmp.card[3] = GetWord(battle_config.reserved_costume_id, 1); + } + // End costume conversion logic (2) + if ((flag = pc_additem(sd, &item_tmp, get_count, LOG_TYPE_COMMAND))) clif_additem(sd, 0, 0, flag); } diff --git a/src/map/battle.cpp b/src/map/battle.cpp index 684c833..88a691b 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -8635,6 +8635,7 @@ bool battle_check_range(struct block_list *src, struct block_list *bl, int range { "item_enabled_npc", &battle_config.item_enabled_npc, 1, 0, 1, }, { "item_flooritem_check", &battle_config.item_onfloor, 1, 0, 1, }, { "bowling_bash_area", &battle_config.bowling_bash_area, 0, 0, 20, }, + { "reserved_costume_id", &battle_config.reserved_costume_id, 999998, 0, INT_MAX, }, { "drop_rateincrease", &battle_config.drop_rateincrease, 0, 0, 1, }, { "feature.auction", &battle_config.feature_auction, 0, 0, 2, }, { "feature.banking", &battle_config.feature_banking, 1, 0, 1, }, diff --git a/src/map/battle.hpp b/src/map/battle.hpp index c26efe3..58ffded 100644 --- a/src/map/battle.hpp +++ b/src/map/battle.hpp @@ -544,6 +544,7 @@ struct Battle_Config int item_enabled_npc; int item_onfloor; // Whether to drop an undroppable item on the map or destroy it if inventory is full. int bowling_bash_area; + int reserved_costume_id; // Costume System int drop_rateincrease; int feature_auction; int feature_banking; diff --git a/src/map/map.cpp b/src/map/map.cpp index 0aee3ce..1cb4df2 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -1950,6 +1950,14 @@ void map_reqnickdb(struct map_session_data * sd, int charid) nullpo_retv(sd); + // Start costume conversion logic (3) + if( battle_config.reserved_costume_id && battle_config.reserved_costume_id == charid ) + { + clif_solved_charname(sd->fd, charid, "Costume"); + return; + } + // End costume conversion logic (3) + tsd = map_charid2sd(charid); if( tsd ) { diff --git a/src/map/pc.cpp b/src/map/pc.cpp index 658984b..2b2a8cf 100755 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -870,7 +870,18 @@ int pc_equippoint_sub(struct map_session_data *sd,struct item_data* id){ int pc_equippoint(struct map_session_data *sd,int n){ nullpo_ret(sd); - return pc_equippoint_sub(sd,sd->inventory_data[n]); + // Start costume conversion logic (4) + int ep = pc_equippoint_sub(sd,sd->inventory_data[n]); + int char_id = 0; + if (battle_config.reserved_costume_id && + sd->inventory.u.items_inventory[n].card[0] == CARD0_CREATE && + (char_id = MakeDWord(sd->inventory.u.items_inventory[n].card[2],sd->inventory.u.items_inventory[n].card[3])) == battle_config.reserved_costume_id) { + if (ep&EQP_HEAD_TOP) { ep &= ~EQP_HEAD_TOP; ep |= EQP_COSTUME_HEAD_TOP; } + if (ep&EQP_HEAD_LOW) { ep &= ~EQP_HEAD_LOW; ep |= EQP_COSTUME_HEAD_LOW; } + if (ep&EQP_HEAD_MID) { ep &= ~EQP_HEAD_MID; ep |= EQP_COSTUME_HEAD_MID; } + } + return ep; + // End costume conversion logic (4) } /** @@ -2582,7 +2593,7 @@ void pc_delautobonus(struct map_session_data* sd, std::vector<s_autobonus> &bonu unsigned int equip_pos_idx = 0; // Create a list of all equipped positions to see if all items needed for the autobonus are still present [Playtester] - for (uint8 j = 0; j < EQI_MAX; j++) { + for (uint8 j = 0; j < EQI_MAX_BONUS; j++) { if (sd->equip_index[j] >= 0) equip_pos_idx |= sd->inventory.u.items_inventory[sd->equip_index[j]].equip; } @@ -2627,7 +2638,7 @@ void pc_exeautobonus(struct map_session_data *sd, std::vector<s_autobonus> *bonu int j; unsigned int equip_pos_idx = 0; //Create a list of all equipped positions to see if all items needed for the autobonus are still present [Playtester] - for(j = 0; j < EQI_MAX; j++) { + for(j = 0; j < EQI_MAX_BONUS; j++) { if(sd->equip_index[j] >= 0) equip_pos_idx |= sd->inventory.u.items_inventory[sd->equip_index[j]].equip; } @@ -10126,7 +10137,7 @@ int pc_load_combo(struct map_session_data *sd) { *------------------------------------------*/ bool pc_equipitem(struct map_session_data *sd,short n,int req_pos,bool equipswitch) { - int i, pos, flag = 0, iflag; + int i, pos, flag = 0, iflag, char_id = 0; struct item_data *id; uint8 res = ITEM_EQUIP_ACK_OK; short* equip_index; diff --git a/src/map/pc.hpp b/src/map/pc.hpp index b52784b..23d1a85 100644 --- a/src/map/pc.hpp +++ b/src/map/pc.hpp @@ -84,7 +84,8 @@ enum equip_index { EQI_SHADOW_SHOES, EQI_SHADOW_ACC_R, EQI_SHADOW_ACC_L, - EQI_MAX + EQI_MAX, + EQI_MAX_BONUS = 10 }; enum prevent_logout_trigger { diff --git a/src/map/status.cpp b/src/map/status.cpp index 09317fd..bd3699b 100644 --- a/src/map/status.cpp +++ b/src/map/status.cpp @@ -3805,7 +3805,7 @@ int status_calc_pc_sub(struct map_session_data* sd, enum e_status_calc_opt opt) running_npc_stat_calc_event = false; // Parse equipment - for (i = 0; i < EQI_MAX; i++) { + for (i = 0; i < EQI_MAX_BONUS; i++) { current_equip_item_index = index = sd->equip_index[i]; // We pass INDEX to current_equip_item_index - for EQUIP_SCRIPT (new cards solution) [Lupus] current_equip_combo_pos = 0; if (index < 0)
I can see a problem in the code without testing it
not sure if there is more , will leave it for you to test
-
10 hours ago, rokimoki said:
Warning are not errors, you should not be afraid of warnings
most errors break the code
most warnings does not break the code
if there is a bug , there is a higher chance to abuse it if it was a warning
like for example a shop that sell item for zeny less then the sell price you will get a warning , still players can abuse it, if you messed up the shop writing you will get and error and the shop wont work
- 2
-
--------------------------------------- *countinarray <array name>{[<start index>]},<array name>{[<start index>]}; This command will check for matches between the array values and return the number of matches. While being optional, if [<start index>] is supplied, the search will begin from the given index value. setarray .@array[0], 100, 200, 300, 400, 500, 600; .@variable = 100; if(countinarray(.@array[0], .@variable)) mes "The number 100 was found in the array .@array"; countinarray(.@array[0], .@variable); //return 1 because the number 100 is an element of the array .@array setarray .@array2[0],100,500; countinarray(.@array[0], .@array2[0]); //return 2 because the numbers 100 and 500 are elements of the array .@array setarray .@array3[0],100,700; countinarray(.@array[0], .@array3[0]); //return 1 because the number 100 is an element of the array .@array //but the number 700 is not an element of the array .@array //also you can change the position between the arrays in the command if(countinarray(.@array[0], .@array3[0]) == countinarray(.@array3[0], .@array[0])) //This is true For more details, see the sample in 'doc/sample/inarray.txt'. ---------------------------------------
Example:
//creating an array with the values with no duplication for(.@i=0;.@i<getarraysize($account_id);.@i++){ if(inarray(.@vtemp,$account_id[.@i]) == -1){ .@vtemp[getarraysize(.@vtemp)] = $account_id[.@i]; } } //now .@vtemp have all the values without duplication //counting for(.@i=0;.@i<getarraysize(.@vtemp);.@i++){ .@v = .@vtemp[.@i]; .@ctemp[.@i] = countinarray($account_id,.@v); } //now .@ctemp have all the values count with the index of the value //the result for(.@i=0;.@i<getarraysize(.@vtemp);.@i++){ debugmes .@ctemp[.@i] + " = " + .@vtemp[.@i]; } //burning the array but extracting only the first 3 (less if there is less then 3 in the array) .@wanted_count = min(getarraysize(.@ctemp),3); while(.@max < .@wanted_count){ .@max++; .@c = max(.@ctemp); .@ndx = inarray(.@ctemp,.@c); .@s = getarraysize(.@result_value); .@result_value[.@s] = .@vtemp[.@ndx]; .@result_count[.@s] = .@ctemp[.@ndx]; deletearray(.@vtemp[.@ndx],1); deletearray(.@ctemp[.@ndx],1); } //end result for(.@i=0;.@i<getarraysize(.@result_value);.@i++){ debugmes .@result_count[.@i] + " = " + .@result_value[.@i]; }
- 3
-
49 minutes ago, DEsMOn said:
I've tried your given solution but doesn't count.
oh i see , line 47
from
setd(".m_" + .@id + "$[" + getarraysize(getd(".m_" + .@id)) + "]",getarg(1));
to
setd(".m_" + .@id + "$[" + getarraysize(getd(".m_" + .@id + "$")) + "]",getarg(1));
- 1
-
1 hour ago, Kakaroto said:
1>atcommand.cpp 1>F:\GitHub\Emulador\src\custom\atcommand.inc(675,36): error C2064: term does not evaluate to a function taking 1 arguments 1>F:\GitHub\Emulador\src\custom\atcommand.inc(675,19): warning C4473: 'sprintf' : not enough arguments passed for format string 1>F:\GitHub\Emulador\src\custom\atcommand.inc(675,19): message : placeholders and their parameters expect 1 variadic arguments, but 0 were provided 1>F:\GitHub\Emulador\src\custom\atcommand.inc(675,19): message : the missing variadic argument 1 is required by format string '%s' 1>battle.cpp 1>Done building project "map-server.vcxproj" -- FAILED. ========== Build: 0 succeeded, 1 failed, 12 up-to-date, 0 skipped ==========
oh I see , when I fixed the warning , I also changed the function call , didn't notice that
will update it
the fix is from
sprintf(mobname, "Mob Name - %s", mob_db(pet_db_ptr->class_)->jname);
to
std::string temp_name = "Mob Name - " + mob_db.find(pet_db_ptr->class_)->jname; strcpy(mobname, temp_name.c_str());
Thank you for notifying me!
- 1
-
-
20 hours ago, kalabasa said:
.@delay = 600; should i change it to 7200? to display 1 hr
and can it display like
Call in 59 minutes
call in 40 minutes
call in 5 minutes
and so on..
yes, yes
#THQ_DELAY/60 = minutes
-
58 minutes ago, DEsMOn said:
I've noticed 1 small issue where the mvp has multiple map spawn that doesn't count
Example These 2 MVP has multiple spawn in field.
Atroce MVP - Kill counts for ra_fild02 but doesn't count for ra_fild03,ra_fild04,ve_fild01,ve_fild02
AddMvp(1785,"ra_fild02","ra_fild03","ra_fild04","ve_fild01","ve_fild02");
Same for Orc Hero - Kill counts for gef_fild14 but doesn't count for gef_fild02
AddMvp(1087,"gef_fild14","gef_fild02");
Rest All fine...
Thank you so much sir you are amazing if u can provide solution for above would be great .
1 Small NPC dedicated on your name small token of appreciation...!
I already did consider the multi field
AddMvp(1785,"ra_fild02","ra_fild03","ra_fild04","ve_fild01","ve_fild02");
to
AddMvp(1785,"ra_fild02"); AddMvp(1785,"ra_fild03"); AddMvp(1785,"ra_fild04"); AddMvp(1785,"ve_fild01"); AddMvp(1785,"ve_fild02");
- 1
-
13 hours ago, DEsMOn said:
Thank you Sader Sir,
Will test n update..!!
I got this error
[Error]:
script error on npc/custom/sadermvprank.txt line 33
parse_callfunc: not enough arguments, expected ','
28 : end;
29 :
30 : OnNPCKillEvent:
31 : .@id = killedrid;
32 : if(inarray(.mvp_id,.@id) != -1){
* 33 : if(inarray(getd(".m_" + .@id + "$")')' != -1){
34 : if((.@ndx = inarray($MVP_KILL_CID,getcharid(0))) == -1){
35 : .@ndx = getarraysize($MVP_KILL_CID);
36 : $MVP_KILL_CID[.@ndx] = getcharid(0);
37 : $MVP_KILL_NM$[.@ndx] = strcharinfo(0);
38 : }replace the line with
if(inarray(getd(".m_" + .@id + "$"),strcharinfo(3)) != -1){
i edited the script in the first post
How to call ItemLink instead of just ItemID
in Scripting Support
Posted
function Slot { set .@s$,getitemname(getarg(0)); switch(.ShowSlot) { case 1: if (!getitemslots(getarg(0))) return .@s$; case 2: if (getiteminfo(getarg(0), ITEMINFO_TYPE) == 4 || getiteminfo(getarg(0), ITEMINFO_TYPE) == 5) return .@s$+" ["+getitemslots(getarg(0))+"]"; default: return .@s$; } }
To