-
Posts
44 -
Joined
-
Last visited
-
Days Won
3
Content Type
Profiles
Forums
Downloads
Jobs Available
Server Database
Third-Party Services
Top Guides
Store
Crowdfunding
Everything posted by ToastOfDoom
-
@Patskie You want to use a variable with the getarraysize value as opposed to calling the function directly inside the for loop. prontera,150,150,0 script Sample 100,{ for ( .@i = 0; .@i < .num_r; .@i += 2 ) { if ( countitem( .r[ .@i ] ) < .r[ .@i + 1 ] ) { mes "Lack of requirements"; close; } } for ( .@i = 0; .@i < .num_r; .@i += 2 ) delitem .r[ .@i ], .r[ .@i + 1 ]; for ( .@i = 0; .@i < .num_p; .@i += 2 ) getitem .p[ .@i ], .p[ .@i + 1 ]; mes "Nice!"; close; OnInit: // item id, amount ( r = requirements | p = prize ) setarray .r[0],7227,5,7179,5; setarray .p[0],1202,1,5013,1; set .num_r, getarraysize(.r); set .num_p, getarraysize(.p); end; } The getarraysize() function quite literally goes through the array checking if each value exists till the end. To put it in a loop like that means the processing time will increase quadratically as you add items. static int32 getarraysize(struct script_state* st, int32 id, int32 idx, int isstring, struct DBMap** ref) { int32 ret = idx; if( isstring ) { for( ; idx < SCRIPT_MAX_ARRAYSIZE; ++idx ) { char* str = (char*)get_val2(st, reference_uid(id, idx), ref); if( str && *str ) ret = idx + 1; script_removetop(st, -1, 0); } } else { for( ; idx < SCRIPT_MAX_ARRAYSIZE; ++idx ) { int32 num = (int32)__64BPRTSIZE(get_val2(st, reference_uid(id, idx), ref)); if( num ) ret = idx + 1; script_removetop(st, -1, 0); } } return ret; }
-
The function you supply with the 'function' function needs to return 'true' (or something that the scripting engine that fulfills a true condition). I believe this means anything that isn't 0 or an empty string. Likewise the same applies to the flag function as well. Easiest way to check if(<variable name>) dispbottom "true"; else dispbottom "false";
-
Toasty's WoE Controller
ToastOfDoom replied to ToastOfDoom's topic in PvP, GvG, WoE, Battleground Script Releases
Fixed... Probably. -
Toasty's WoE Controller
ToastOfDoom replied to ToastOfDoom's topic in PvP, GvG, WoE, Battleground Script Releases
@Euphy =O!! You broke my controller? =( Sigh..now i have to make an update... Might as well make it awesomener while i'm at it.... -
Can any one please fix this script(About warper).
ToastOfDoom replied to vijay30393's question in Script Requests
You're comparing a number with a string if(.@atcmd_parameters$[0] != 30){ needs to be if(.@atcmd_parameters$[0] != "30"){ You shouldn't really use useatcmd but instead redefine all the @go warp points in the scripting code. You should only use that command if it's not possible to replicate the existing @command function using script. In this case warping a player is very easily done. Also next time please post the error you get in the mapserver as well as your code. Just saying "give's an error in mapserver" doesn't tell us much. -
@ryokem Feefty said it was for their daily quest script. Of course I have no way to be sure but its perfectly reasonable for me to guess what they are using it for and to provide suggestions based upon that. There's no reason you should be shutting down someone's suggestions like this. It just locks out 'out of the box' suggestions which doesn't help anyone at all. There's not too many instances where you really do need to set all of a certain # var at a certain time. Like you can't even use the var if the player is offline. @lighta Using gettimetick(2) / 86400 will give a 'day tick' using epoch time. Will work till like 2036. I can't remember if it uses UTC time or server time though...
-
You could always model the data differently. Eg. Lets say you have a quest you want players to do only once every day. You could: a. Check for a variable every time they do the quest. If it is set then they've done it already and don't let them do the quest. Reset every variable at midnight. OR b. Set a variable with the date everytime they do the quest. Then check using that variable that it's been at least 1 day before they do the quest.(no messy super reset using sql)
-
Anyone want to make Roulette script?
ToastOfDoom replied to Peopleperson49's question in Script Requests
Don't think i'll get around to actually writing the script but here is the model i'll use for calculating if a player had won. Don't read if you still want to think about it and figure out your own method. -
Limit PvP for Once per KILLEDRID per Day
ToastOfDoom replied to serakh00's question in Scripting Support
@annie They mean you only get a PVP point if you haven't already killed them today. So you kill them the 1st time and you get a point. If you kill them a 2nd time you don't get a point unless it's been 24hrs since you last killed that person. @serakh00 If you want us to optimise your system you need to post your script and work. -
How about implementing some kind of 'virtual' player. The player can be shared between NPCs and all existing player modification functions can be used. Used something like this... .@vp_gid = CreateVirtualPlayer(); attachrid(.@vp_gid); statusup2(bStr, 100); UseSkillToPC(.@vp_gid, <skill_id>, <skill_level>, <target_gid>); UseSkillToPC(.@vp_gid, <skill_id>, <skill_level>, <map>, <x>, <y>); DestroyVirtualPlayer(.@vp_gid); Casting source can be set to the invoking NPC or nothing in the case of Floating NPCs.
-
@ryokem There is a trick where if you leave a menu item blank, it won't show, but it will still use up the index. if ( .@currentpage ) .@tmp$[0] = "Previous Page"; In this case the first page actually looks something like this ":<item1>:<item2>:<item3>:Next Page" Note that it starts with a colon ':'. This means index 1 (adjusted to be 0 later) will always correspond to 'Previous Page' regardless of wherever it is shown or not. Likewise the same thing happens for the 'Next Page' item only with a different index. This method cuts down on alot of extra math, loops and comparisons. However it leaves a security flaw in that players can possibly get to non wanted menus through packet manipulation. Therefore scripters will need to do further checks in their script after the menu selection depending on the usage to insure that selection is valid.
-
@annie Looking good =D. Yours definitely runs better. I think if you Put the next/previous lines into the tmp$ array and crunch it all with implode at the End It would make it extra sexy. tmp$[0] = previous page; tmp$[.items_per_page + 1] = next page; Ps: on phone atm so cant script. ^^;
-
Couldn't we change it so if the MOTD is blank it just wouldn't show. That way if a user requires a more advanced MOTD they can disable the existing implementation still add their own thing using OnPCLoginEvent. Having a script reference directly hardcoded into source feels very weird for me.
-
you can already do this using a combination of getd and setarray. setarray getd(".test[0]"), 1, 2, 3, 4, 5; Also sorry for the necro... =P
-
You're missing the tabs in the function & npc headers. function<TAB>script<TAB>command__<tab>{ ... -<tab>script<tab>fixautoattack<tab>{ ...
-
Since rathena added the string commands we can now use the implode function to create dynamic menus. prontera,156,174,4 script test 100,{ do { //Add 'Previous Page' to index 0 if needed .@menu$ = (.@page)?"Previous Page:":":"; //Add menu items copyarray .@menuar$[0], .itemsnames$[.@page * .items_per_page], .items_per_page; set .@menu$, .@menu$ + implode(.@menuar$, ":"); //Add 'Next Page' to end if needed set .@menu$, .@menu$ + ((.max_page - .@page)?":Next Page":""); //Compute number of items (I think this can look better) .@num_items_in_menu = .num_items - (.@page * .items_per_page); .@num_items_in_menu = (.@num_items_in_menu > .items_per_page)?.items_per_page:.@num_items_in_menu; .@menu = select(.@menu$) - 1; if(.@menu == .@num_items_in_menu + 1) { //next page .@page++; } else if (.@menu) { //selected item break; } else { //previous page .@page--; } } while (1); .@index = .@page * .items_per_page + .@menu - 1; dispbottom "selected: " + .itemsids[.@index] + ": " + .itemsnames$[.@index]; close; OnInit: setarray .itemsids[0],5360,5361,5363,5362,5364; .items_per_page = 15; .num_items = getarraysize(.itemsids); .max_page = .num_items / .items_per_page + ((.num_items % .items_per_page) > 0) - 1; //Prestore item names while(.@i < .num_items) { setarray .itemsnames$[.@i], getitemname(.itemsids[.@i]); .@i++; } end; }
-
It's actually not that surprising. An 'int' is stored using 32 bits. One bit is used as a sign so you effectively have 31 bits for the number. 2^31 = 2,147,483,648 I do wonder why it's a signed int though. There really isn't a case where you can have negative zeny.
-
Its not really a matter of how much processing power but more about organising Data better. If you have all your data in the global scope it is very easy for other scripts to accidentally access and modify that same data.
-
I recall that Using getd inside getvariableofnpc Works. Getvariableofnpc(getd("var"), <npc>) Sorry I can't test this ATM.
-
To duplicate the ladder you need to somehow duplicate the following variables in the script. Player scope variables: PVPKills PVPDeaths #PVPDeathsAccount @PVPDeathstoday Server scope variables: $terces_PVP_names$[] $terces_PVP_kills[] $terces_PVP_deaths[] $terces_PVP_times[] $@LadderLength (maybe a few others) The way I would do it is to simply append the map name on the end of it using setd/getd. eg instead of set PVPDeaths, PVPDeaths +1; you have setd("PVPDeaths_" + strcharinfo(3)); This kind of generic type data layout will let you very easily add as many maps as you want (provided you don't run out of memory) but is rather complex to implement.
-
Dispell all buffs on entering pvp room
ToastOfDoom replied to miyakee's question in Scripting Support
Hmm...haven't done this for a while so lets see how it goes. (forgive any syntax errors, still setting up my server so I can't test =P) This one is abit different. During dispell only needs to loop as many times as needed without having to do any comparisons. Buff list was taken from the dispell skill inside source. - script dispeller -1,{ function DispellBuff; OnInit: freeloop(1); DispellBuff(SC_WEIGHT50); DispellBuff(SC_WEIGHT90); DispellBuff(SC_HALLUCINATION); DispellBuff(SC_STRIPWEAPON); DispellBuff(SC_STRIPSHIELD); DispellBuff(SC_STRIPARMOR); DispellBuff(SC_STRIPHELM); DispellBuff(SC_CP_WEAPON); DispellBuff(SC_CP_SHIELD); DispellBuff(SC_CP_ARMOR); DispellBuff(SC_CP_HELM); DispellBuff(SC_COMBO); DispellBuff(SC_STRFOOD); DispellBuff(SC_AGIFOOD); DispellBuff(SC_VITFOOD); DispellBuff(SC_INTFOOD); DispellBuff(SC_DEXFOOD); DispellBuff(SC_LUKFOOD); DispellBuff(SC_HITFOOD); DispellBuff(SC_FLEEFOOD); DispellBuff(SC_BATKFOOD); DispellBuff(SC_WATKFOOD); DispellBuff(SC_MATKFOOD); DispellBuff(SC_DANCING); DispellBuff(SC_EDP); DispellBuff(SC_AUTOBERSERK); DispellBuff(SC_CARTBOOST); DispellBuff(SC_MELTDOWN); DispellBuff(SC_SAFETYWALL); DispellBuff(SC_SMA); DispellBuff(SC_SPEEDUP0); DispellBuff(SC_NOCHAT); DispellBuff(SC_ANKLE); DispellBuff(SC_SPIDERWEB); DispellBuff(SC_JAILED); DispellBuff(SC_ITEMBOOST); DispellBuff(SC_EXPBOOST); DispellBuff(SC_LIFEINSURANCE); DispellBuff(SC_BOSSMAPINFO); DispellBuff(SC_PNEUMA); DispellBuff(SC_AUTOSPELL); DispellBuff(SC_INCHITRATE); DispellBuff(SC_INCATKRATE); DispellBuff(SC_NEN); DispellBuff(SC_READYSTORM); DispellBuff(SC_READYDOWN); DispellBuff(SC_READYTURN); DispellBuff(SC_READYCOUNTER); DispellBuff(SC_DODGE); DispellBuff(SC_WARM); DispellBuff(SC_SPEEDUP1); DispellBuff(SC_AUTOTRADE); DispellBuff(SC_CRITICALWOUND); DispellBuff(SC_JEXPBOOST); DispellBuff(SC_INVINCIBLE); DispellBuff(SC_INVINCIBLEOFF); DispellBuff(SC_HELLPOWER); DispellBuff(SC_MANU_ATK); DispellBuff(SC_MANU_DEF); DispellBuff(SC_SPL_ATK); DispellBuff(SC_SPL_DEF); DispellBuff(SC_MANU_MATK); DispellBuff(SC_SPL_MATK); DispellBuff(SC_RICHMANKIM); DispellBuff(SC_ETERNALCHAOS); DispellBuff(SC_DRUMBATTLE); DispellBuff(SC_NIBELUNGEN); DispellBuff(SC_ROKISWEIL); DispellBuff(SC_INTOABYSS); DispellBuff(SC_SIEGFRIED); DispellBuff(SC_FOOD_STR_CASH); DispellBuff(SC_FOOD_AGI_CASH); DispellBuff(SC_FOOD_VIT_CASH); DispellBuff(SC_FOOD_DEX_CASH); DispellBuff(SC_FOOD_INT_CASH); DispellBuff(SC_FOOD_LUK_CASH); DispellBuff(SC_SEVENWIND); DispellBuff(SC_MIRACLE); DispellBuff(SC_S_LIFEPOTION); DispellBuff(SC_L_LIFEPOTION); DispellBuff(SC_INCHEALRATE); DispellBuff(SC_ELECTRICSHOCKER); DispellBuff(SC__STRIPACCESSORY); DispellBuff(SC_COCKTAIL_WARG_BLOOD); DispellBuff(SC_MINOR_BBQ); DispellBuff(SC_DROCERA_HERB_STEAMED); DispellBuff(SC_PUTTI_TAILS_NOODLES); DispellBuff(SC_NEUTRALBARRIER_MASTER); DispellBuff(SC_NEUTRALBARRIER); DispellBuff(SC_STEALTHFIELD_MASTER); DispellBuff(SC_STEALTHFIELD); DispellBuff(SC_GIANTGROWTH); DispellBuff(SC_MILLENNIUMSHIELD); DispellBuff(SC_REFRESH); DispellBuff(SC_STONEHARDSKIN); DispellBuff(SC_VITALITYACTIVATION); DispellBuff(SC_FIGHTINGSPIRIT); DispellBuff(SC_ABUNDANCE); DispellBuff(SC__SHADOWFORM); DispellBuff(SC_LEADERSHIP); DispellBuff(SC_GLORYWOUNDS); DispellBuff(SC_SOULCOLD); DispellBuff(SC_HAWKEYES); DispellBuff(SC_GUILDAURA); DispellBuff(SC_PUSH_CART); DispellBuff(SC_RAISINGDRAGON); DispellBuff(SC_GT_ENERGYGAIN); DispellBuff(SC_GT_CHANGE); DispellBuff(SC_GT_REVITALIZE); DispellBuff(SC_REFLECTDAMAGE); DispellBuff(SC_INSPIRATION); DispellBuff(SC_EXEEDBREAK); DispellBuff(SC_FORCEOFVANGUARD); DispellBuff(SC_BANDING); DispellBuff(SC_DUPLELIGHT); DispellBuff(SC_EXPIATIO); DispellBuff(SC_LAUDAAGNUS); DispellBuff(SC_LAUDARAMUS); DispellBuff(SC_GATLINGFEVER); DispellBuff(SC_INCREASING); DispellBuff(SC_ADJUSTMENT); DispellBuff(SC_MADNESSCANCEL); DispellBuff(SC_ASSUMPTIO); DispellBuff(SC_BERSERK); DispellBuff(SC_SATURDAYNIGHTFEVER); freeloop(0); end; OnDispell: while(.@i < .buffCount) { sc_end getd(".buff_" + .@i); .@i += 1; } end; function DispellBuff { //<buff_id> setd(".buff_" + .buffCount, getarg(0)); .buffCount += 1; return; } } Run using doevent "dispeller::OnDispell"; -
While yes this can be very easily implemented using bindatcmd, it would force you to go through the script engine pipeline which is abit excessive for just an extra comparison every atcommand.
-
KingKronos' Dynamic [Quest/Full/WoE/...] Warper 1.1
ToastOfDoom replied to MusiDex's topic in Utility Script Releases
I'm glad someone out there understands my script enough to take ideas out of it =P Ah... There is a reason for this. When I write scripts I tend to put memory usage over processing time. A few hundred extra variables is considered cheap compared to doing an extra 2-3 comparisons/retrievals per map per player click in my book. -
Was some code I added a while ago that prevented the script from completely failing on stable servers if people loaded the wrong version. The sideeffect was that it put up a harmless warning message. May remove it in future release since stable isn't used much anymore.