Jump to content

KeyWorld

Members
  • Posts

    379
  • Joined

  • Last visited

  • Days Won

    11

Everything posted by KeyWorld

  1. Comment the line, or add a "{" after the for(). Yeah I didn't test the script
  2. i just copy the header from the base npc at topic #1
  3. Funny thing, I did the same than Euphy... but mine is easier to edit prt_in.gat,172,140,3 script Weapons Shop 951,{ function enum; switch( BaseJob ) { case Job_Priest: setarray .@priority, .TYPE_MACE, .TYPE_WAND, .TYPE_BOOK, .TYPE_KNUCKLE; break; case Job_Assassin: setarray .@priority, .TYPE_DAGGER, .TYPE_KATAR, .TYPE_SWORD; break; case Job_Monk: setarray .@priority, .TYPE_MACE, .TYPE_KNUCKLE; break; case Job_Sage: setarray .@priority, .TYPE_WAND, .TYPE_BOOK; break; case Job_Rogue: setarray .@priority, .TYPE_DAGGER, .TYPE_SWORD, .TYPE_BOW; break; case Job_Bard: setarray .@priority, .TYPE_BOW, .TYPE_INSTRUMENT, .TYPE_DAGGER; break; case Job_Dancer: setarray .@priority, .TYPE_BOW, .TYPE_WHIP, .TYPE_DAGGER; break; case Job_Gunslinger: setarray .@priority, .TYPE_GUN; break; case Job_Ninja: setarray .@priority, .TYPE_KUNAI; break; // Base class, if not in list default: switch( BaseClass ) { case Job_Novice: setarray .@priority, .TYPE_DAGGER, .TYPE_SWORD; break; case Job_Swordman: setarray .@priority, .TYPE_SWORD, .TYPE_SPEAR; break; case Job_Mage: setarray .@priority, .TYPE_WAND; break; case Job_Archer: setarray .@priority, .TYPE_BOW; break; case Job_Acolyte: setarray .@priority, .TYPE_MACE, .TYPE_WAND; break; case Job_Merchant: setarray .@priority, .TYPE_AXE, .TYPE_DAGGER, .TYPE_MACE, .TYPE_SWORD; break; case Job_Thief: setarray .@priority, .TYPE_DAGGER, .TYPE_BOW; break; } } set .@size, getarraysize(.@priority); // Priority menu if ( .@size ) { for (set .@menu$, "^FF0000"; .@i<.@size; set .@i, .@i + 1 ) { set .@type, .@priority[.@i]; set .@menu$, .@menu$ + ( .@i ? ":" : "") + .TYPE_NAME$[.@type]; set .@list[.@i], .@type; set .@types[.@type], 1; } } // Other menu for ( set .@menu$, .@menu$ + "^0000FF"; .@j<.TYPE_MAX; set .@j, .@j + 1 ) { if ( !.@types[.@j] ) { set .@menu$, .@menu$ + ( .@size+.@j ? ":" : "" ) + .TYPE_NAME$[.@j]; set .@types[.@j], 1; set .@list[.@size+.@j], .@j; } } // Display menu callshop .TYPE_NAME$[ .@list[select(.@menu$) - 1] ]; close; OnInit: // Constantes enum( .TYPE_DAGGER, .TYPE_SWORD, .TYPE_SPEAR, .TYPE_AXE, .TYPE_MACE, .TYPE_WAND, .TYPE_BOW, .TYPE_KNUCKLE, .TYPE_INSTRUMENT, .TYPE_WHIP, .TYPE_BOOK, .TYPE_GUN, .TYPE_KUNAI, .TYPE_KATAR, .TYPE_MAX ); // Define name base on constantes set .TYPE_NAME$[.TYPE_DAGGER], "Daggers"; set .TYPE_NAME$[.TYPE_SWORD], "Swords"; set .TYPE_NAME$[.TYPE_SPEAR], "Spears"; set .TYPE_NAME$[.TYPE_AXE], "Axes"; set .TYPE_NAME$[.TYPE_MACE], "Maces"; set .TYPE_NAME$[.TYPE_WAND], "Wands"; set .TYPE_NAME$[.TYPE_BOW], "Bows"; set .TYPE_NAME$[.TYPE_KNUCKLE], "Knuckles"; set .TYPE_NAME$[.TYPE_INSTRUMENT], "Instruments"; set .TYPE_NAME$[.TYPE_WHIP], "Whips"; set .TYPE_NAME$[.TYPE_BOOK], "Books"; set .TYPE_NAME$[.TYPE_GUN], "Guns"; set .TYPE_NAME$[.TYPE_KUNAI], "Huuma and Kunai"; set .TYPE_NAME$[.TYPE_KATAR], "Katars"; // Enum functions function enum { for ( set .@size, getargcount(); .@i<.@size; set .@i, .@i+1 ) set getarg(.@i), .@i; } } - shop Daggers -1,1203:-1,1201:-1,1202:-1,1206:-1,1204:-1,1205:-1,1209:-1,1207:-1,1208:-1,1212:-1,1210:-1,1211:-1,1215:-1,1213:-1,1214:-1,1218:-1,1216:-1,1217:-1,1221:-1,1219:-1,1220:-1,1222:-1,1226:-1,1245:-1,1246:-1,1247:-1,1248:-1,1249:-1,13000:-1,13003:-1,13004:-1 - shop Swords -1,1103:-1,1101:-1,1102:-1,1106:-1,1104:-1,1105:-1,1109:-1,1107:-1,1108:-1,1112:-1,1110:-1,1111:-1,1113:-1,1114:-1,1121:-1,1119:-1,1120:-1,1122:-1,1125:-1,1123:-1,1128:-1,1126:-1,1127:-1,1129:-1,1149:-1,1146:-1,1147:-1,1118:-1,1116:-1,1117:-1,1153:-1,1151:-1,1152:-1,1156:-1,1154:-1,1155:-1,1159:-1,1157:-1,1158:-1,1160:-1,1162:-1,1163:-1,31172:-1,1172:-1 - shop Spears -1,1403:-1,1401:-1,1402:-1,1406:-1,1404:-1,1405:-1,1409:-1,1407:-1,1408:-1,1411:-1,1453:-1,1451:-1,1452:-1,1456:-1,1454:-1,1455:-1,1459:-1,1457:-1,1458:-1,1462:-1,1460:-1,1461:-1,1465:-1,1463:-1,1464:-1 - shop Axes -1,1303:-1,1301:-1,1302:-1,1353:-1,1351:-1,1352:-1,1356:-1,1354:-1,1355:-1,1359:-1,1357:-1,1358:-1,1362:-1,1360:-1,1361:-1 - shop Maces -1,1503:-1,1501:-1,1502:-1,1506:-1,1504:-1,1505:-1,1509:-1,1507:-1,1508:-1,1512:-1,1510:-1,1511:-1,1519:-1,1520:-1,1521:-1,1513:-1,1514:-1,1515:-1,1516:-1,1517:-1,1518:-1,1522:-1,1532:-1 - shop Wands -1,1603:-1,1601:-1,1602:-1,1606:-1,1604:-1,1605:-1,1609:-1,1607:-1,1608:-1,1612:-1,1610:-1,1611:-1,1617:-1,1618:-1,1619:-1,1620:-1 - shop Bows -1,1703:-1,1701:-1,1702:-1,1706:-1,1704:-1,1705:-1,1709:-1,1707:-1,1708:-1,1712:-1,1710:-1,1711:-1,1713:-1,1715:-1,1714:-1,1716:-1,1726:-1,1721:-1 - shop Knuckles -1,1801:-1,1802:-1,1803:-1,1804:-1,1805:-1,1806:-1,1807:-1,1808:-1,1809:-1,1810:-1,1811:-1,1812:-1 - shop Instruments -1,1901:-1,1902:-1,1903:-1,1904:-1,1905:-1,1906:-1,1907:-1,1908:-1,1909:-1,1910:-1,1921:-1,1911:-1,1912:-1,1913:-1 - shop Whips -1,1950:-1,1951:-1,1952:-1,1953:-1,1954:-1,1955:-1,1956:-1,1957:-1,1958:-1,1959:-1,1960:-1,1961:-1,1963:-1 - shop Books -1,1550:-1,1551:-1,1552:-1,1553:-1,1568:-1,1554:-1,1569:-1,1570:-1,1556:-1,1571:-1,1557:-1,1578:-1 - shop Guns -1,13102:-1,13103:-1,13150:-1,13151:-1,13152:-1,13163:-1,13164:-1,13165:-1,13166:-1,13154:-1,13155:-1,13168:-1,13169:-1 - shop Huuma and Kunai -1,13010:-1,13011:-1,13007:-1,13008:-1,13012:-1,13013:-1,13006:-1,13300:-1,13301:-1,13302:-1,13303:-1,13311:-1,13313:-1,13314:-1,13315:-1,13312:-1 - shop Katars -1,1250:-1,1251:-1,1252:-1,1253:-1,1254:-1,1255:-1 I love the AnnieRuru way Edit @Annie: You define .@job at the begenning but never used it ? Should be .menu$[.@job] ? Isn't it better to, instead of having your switch, just do a "set .@job, BaseClass;" and remove after what you don't want ?
  4. You have to use doevent for the attachrid stuff tu avoid problem with next, menu, etc. attachrid .@aid; doevent "mynpc::OnAttach"; end; OnAttach: <stuff>; About the setnpcdisplay, it has to be IN the npc.
  5. if( countitem(632) < 1 ) { mes "You do not have Fatty Chubby."; close; } delitem 632,1;
  6. "repair" is a script command, you can't use it as a label. So you have to change the name to something else.
  7. Because it's only used in the char-server. "battle/" folder just contains data for the map-server.
  8. The bitmask operation is as fast as + - * operators in rathena so it's faster than using pow() / etc But I agree, the script engine sux, but it will be too difficult to add POO to the engine, it will be faster (and cleaner) to rewrite it from scratch. The main problem is just that every guys are familiars to the current way to script and changing it on something else will destabilize them. Funny to see there is nothing related to bitmask on the wiki °°
  9. Well... you are interested, we are talking about bit-mask, so maybe it can inspired some guys around here. So, as I said, I used bit-mask in my chess script. This script is not released because it's a work in progress I can't test AND because since the CORE is done, I'm not really motivate to do all the rest (npc to register etc.). When loading I generate some constants (fuck indent): // Constantes set .WHITE, 1 << 0; set .BLACK, 1 << 1; set .NONE, 1 << 2; set .OVERFLOW, 1 << 3; set .PAWN, 1 << 4; set .KNIGHT, 1 << 5; set .BISHOP, 1 << 6; set .ROOK, 1 << 7; set .KING, 1 << 8; set .QUEEN, .BISHOP | .ROOK; And I use this constant each time in the script to optimize the script and make it easy readable. So basically, setting the chess board: // Define the board setarray .board[81], .ROOK|.BLACK, .KNIGHT|.BLACK, .BISHOP|.BLACK, .QUEEN|.BLACK, .KING|.BLACK, .BISHOP|.BLACK, .KNIGHT|.BLACK, .ROOK|.BLACK; setarray .board[71], .PAWN|.BLACK, .PAWN |.BLACK, .PAWN |.BLACK, .PAWN |.BLACK, .PAWN|.BLACK, .PAWN |.BLACK, .PAWN |.BLACK, .PAWN|.BLACK; setarray .board[21], .PAWN|.WHITE, .PAWN |.WHITE, .PAWN |.WHITE, .PAWN |.WHITE, .PAWN|.WHITE, .PAWN |.WHITE, .PAWN |.WHITE, .PAWN|.WHITE; setarray .board[11], .ROOK|.WHITE, .KNIGHT|.WHITE, .BISHOP|.WHITE, .QUEEN|.WHITE, .KING|.WHITE, .BISHOP|.WHITE, .KNIGHT|.WHITE, .ROOK|.WHITE; ----------------------------------------------- When player click on a piece, I set a new constant called .ENEMY based on the enemy color. And all you need to do after, is to check the class, and do what you want. Example with the pawn movement: /// Find movement for PAWN if ( .class & .PAWN ) { // Find if the pawn go to the top or to the down set .@_to, .class & .WHITE ? 1 : -1 ; // Normal movement if ( callfunc( "Chess.get_class", .x, .@y + .@_to ) & .NONE ) // no piece here { callfunc( "Chess.save_cell", .x, .y + .@_to ); // Move to +2, if not moved yet set .@start_point, .class & .WHITE ? 2 : 7; if ( .y == .@start_point && callfunc( "Chess.get_class", .x, .y + .@_to * 2 ) & .NONE ) callfunc( "Chess.save_cell", .x, .y + .@_to * 2 ); } // Attack movement on right if ( callfunc( "Chess.get_class", .x + 1, .y + .@_to ) & .ENEMY ) callfunc( "Chess.save_cell", .x + 1, .y + .@_to ); // Attack movement on left if ( callfunc( "Chess.get_class", .x - 1, .y + .@_to ) & .ENEMY ) callfunc( "Chess.save_cell", .x - 1, .y + .@_to ); So I extend the system. Just with bitmask I can know if there is someone in a case (!.NONE, .KING, .ROOK, ...), his color (.WHITE/.BLACK), if it's an enemy (.ENEMY), if I can move here (.MOVABLE) or if I'm out of the board (.OVERFLOW), etc. I also start a little AI, but not finished it yet. ----------------------------------------------- It's just an example. There are a lot of better way to use bitmask, but it's awesome when you know how to use it I remember this topic: http://www.eathena.ws/board/index.php?showtopic=273636 When it comes to my brain that this script will be far more optimized using a bitmask check
  10. Well it's difficult for me to explain, it's not my native language. You have to know that an int variable use 32 bits, here the representation in bit of 315732 : 1001101000101010100. So with bitmask operator, you can access all 32 bits used in an int variable and it's useful to store booleans values (and other things, but I will not explain here). So to really simplify you can use '&' to get and '|' to add values. I use >> << to access values at a specify index. So basically: // check for the .@index bit in .@var if ( .@var & 1 << .@index ) dothis; // Set on bit set .@var, .@var | 1 << .@index; // Set off bit set .@var, .@var & ~ (1<<.@index); Note: index can be a number between 0 and 31. I would like to show my chess script, but it's difficult to select just some parts of it for this topic.
  11. Ok I see what you mean. Yeah it's possible to use this solution, I already use it on the past. But the only advantage is to having the ability to store 10 values (9: 0-9 values and 1: 0-1 value). But in his script, he doesn't need to store values in variables, just need to check if a variable is set, so bit-mask is more natural to use in this case (and faster). if ( var & 1 << index ); set var, var | 1 << index; Vs: if ( var / pow(10,index) % 10 ); set var, var%pow(10,index) + value * pow(10,index) + var/pow(10,index+1)*pow(10,index+1); // or using setchar, charat.
  12. It's missing bracket. if( Class == Job_Novice ){ mes "Novice cant join."; close; } if ( getcharid(1) ) { mes "You have a party you cannot enter"; close; } mes "[Mr. Manager]"; mes "Hello What can I do for you?"; next;
  13. You are talking about how to made the script simpler, not how to save space. Or I don't get it and ask you to show me, with an example if you want, how by using more variables, you can save more slots.
  14. getcharid(1) return the party_id of the character. So basically: if ( getcharid(1) ) mes "You have a party !"; else mes "You don't have a party !"; close;
  15. @Emistry It's not a stable script. When log in you are setting some variables to the player to find it easily. @ArrayIndex = .@array; @Slot = .@size; Whe log out, you removed his index in the array: deletearray getd(".PlayerArray"+@ArrayIndex+"$["+@Slot+"]"),1; Scenario: - 3 players are online, give an array of : [ A, B, C ] with local variable for index: (A:0, B:1, C:2). - Player A log out, result online players: [b, C], with local variable: (B:1, C:2) - Player B log out, result online players: . You need to update each @ArrayIndex value when someone log out. You need also to update .array_size to avoid useless loop sometimes.
  16. I don't say it's wrong to use a method or another, I say it's better to not wasting space by creating multiples vars.I don't get your sentence about bitmask, the result variable is an INT set by booleans (understand boolean as 0-1 for each bits (0-30) in the INT variable). @garet999 Not bad, The OnPcLogoutEvent and OnPCDieEvent can be merged. I don't love the getd ("$@SPVP" + .@PVPUIP$) stuff, it can be improve.
  17. I want to participate @garet999 Good job for one of your first script. Just something, this part of code will never be executed. set .@bonus_ticket,rand(50); if (.@bonus_ticket == 50) getitem 5378,1; // Bunny top hat 2% chance rand(50) giver a result in range 0-49. @Ryokem No, I agree again with Annie. We are limited with PC variables and have to use some stuff to don't reach the server limit. We don't care about how it's stored in the DB (and even it's always smaller to store 30 booleans into one INT (4 bytes) instead of having 30 INT with values 0-1 (4*30 bytes) ). @GmOcean I have to agree with Annie, using your getd(".") stuff will be reset on each reloadscript, reboot, crash and pollute the script buffer Edit: Yeah string can be used too
  18. No.The error is here: select @menu$-1; It should be set .@val, select(@menu$)-1; Or: select @menu$;
  19. Change .@map$ to .map$. Edit: And also remove the "- 1" in the for() condition.
  20. As far I know, empty menu are not send to the client, so no hack possible here. I never have this problem on eA. Maybe you didn't do it in the good way.Well even if the topic is resolved (enough examples I think lol), gimme a try. The script is not tested, but it's the same way than other scripters here : prontera,100,100,4 script item_menu 100,{ do { set .@choice, select(.menu$[.@page]) - 1; if ( .@choice && .@choice <= .page_size ) break; set .@page, .@page + (!!.@choice) * 2 - 1; } while( 1 ); set .@index, .@page * .page_size + .@choice - 1; dispbottom .item_name$[.@index]; close; OnInit: set .page_size, 5; setarray .item_id, 4001, 4002, 4003, 4004, 4005, 4006, 4007, 4008, 4009; set .@size, getarraysize(.item_id); while ( .@i<.@size ) { set .@offset, .@i/.page_size; set .item_name$[.@i], getitemname( .item_id[.@i] ); if ( .@i && !(.@i % .page_size ) ) set .menu$[.@offset], "Previous"; set .menu$[.@offset], .menu$[.@offset] + ":" + .item_name$[.@i]; set .@i, .@i + 1; if ( .@i<.@size && !(.@i % .page_size ) ) set .menu$[.@offset], .menu$[.@offset] + ":Next"; } }
  21. You forget a change: - if( .status == 0 ) + set .@type,atoi(strnpcinfo(2)); + if( getd(".n_"+.@type+"_status") == 0 )
  22. Well, should be enough: - script 10minForYgg -1,{ OnPCLoginEvent: sleep2 10 * 60 * 1000; // wait 10 minutes if ( checkvending() != 2 ) { // Skip autotrade getitem 607, 1; dispbottom "You received 1 Yggdrasil Berry by playing 10 minutes."; goto OnPcLoginEvent; } }
  23. Hi goddameit ! Did you test with multiple NPC ? I don't think it will work. You use "duplicate" and all variables are NPC variables, so all configs are share between NPC, and should be overwrite each time you ask to a new NPC to follow you.
  24. Do you have a backup ?... If yes, just get all data related to the account_id, get all char_id from the acccount, get all data related to this char_id. Just import the file with all the data you extract and that's all. But you have to know, a rollback for only one character is not a good idea.
×
×
  • Create New...