GmOcean
-
Content Count
371 -
Joined
-
Last visited
-
Days Won
8
Posts posted by GmOcean
-
-
I agree with Playtester and csnv, while I myself are in the same position as yourself, I have recently increased the amount of work I do from script -> source code. A lot (~85%) of the stuff I write in src, doesn't work. But the 15% that did work, I am proud to say I did all on my own with little to no help aside from looking at source code for references, and the times I ask for it in source_support section ( very good place if you get stuck ).
I can even go as far to say that after just 2-3 months of experimentation, I was able to make 2 working commands ( src code was moderately borrowed from existing ) with the plugin system.
So believe me when I say, it's not some unreachable place or goal. With a little bit of time and some passionate effort, you can get there, because I know I'm still trying and slowly moving towards that position! Learners rally!!
-
@Garr - Didn't see the .@j++ at the end. But yes, in order to fix this, he would need to run 2 separate loops, 1 to delete all items and the second to give them back bound. At least this is the simplest way to do it.
-
Well, for one your using ' .@i ' in your loop. But in the commands delitem2 and getitembound2 your using ' .@j '. I'm going to assume your only testing this with 2 items in your inventory. If this is the case then only 1 item is going to be bound, since .@j has a value of zero and never get's increased.
TL;DR: change all .@j to .@i or vice-versa
-
Sorry my bad, I meant to use getmonsterinfo( .@i, 0); but I forgot to change it after I was done writing out the template. I updated my previous post. And again, I haven't tested whether or not it will fully work, I just know it doesn't have syntax errors.
-
Perhaps something like this:
- script sql_quest_generator -1,{OnHuntingCreate:freeloop(1); // Freeloop to prevent infinite loop error.while( .@hunting != .hunting_generate ){ // Loop through the below until a total of (.hunting_generate) amount of quests have been created. .@a = rand(.min_hunting_objective, .max_hunting_ojbective); // Select a random amount of objectives for this quest. .@name$ = "Hunting:"; // Start of the quest name. // Loop the below until the selected amount of objectives have been added to the proper variables. while( .@b != .@a ){ .@i = rand(1001,3000); // Selecting a random mob_id # from 1001 (Scorpion) -> 3000 ( Just going beyond what exists to add support for custom mobs ). if( !compare( .blacklist$, ""+ getmonsterinfo( .@i, 0 ) +"" ) ){ // Compares monster ID number to see if it is blacklisted or not. .@mob_objectives[.@b] = .@i; // Adds the monster as an objective. .@mob_obj_amount[.@b] = rand(.min_hunting_amount, .max_hunting_amount); // Adds a random amount to be killed to complete that objective. .@name$ = .@name$ + getmonsterinfo( .@i, 0 ); // Adds the monster's name as part of the quest name. .@b++; } } // We create an entry in our custom quest_database using just the Quest name for now. // This will serve as a pointer when adding in all the objectives later, since the amounts were dynamically chosen and not set in stone. query_sql("INSERT INTO quest_database `quest_name` = '"+ .@name$ +"'"); // Loop through this until ALL objectives & the amount needed to complete it, have been added to the quest we listed above. while( .@c < getarraysize( .@mob_objectives ) ){ // Adding in each objective and it's amount to the quest we just created above. query_sql("Update quest_database SET( `obj"+ .@c +"`, `amt"+ .@c +"'`) VALUES( '"+.@mob_objectives[.@c]+"', '"+.@mob_obj_amount[.@c]+"') WHERE `quest_name`='"+ .@name$ +"'"); .@c++; } // Set this variable +1 to say we have completed creating a quest. And to continue looping if not all of them have been created. .@hunting++;}// Freeloop(0) to let server know we are done looping and to stop trying to prevent infinite loops.freeloop(0);end;// This is where the settings go to configure the above to do what you want.OnInit:.hunting_generate = 3; // How many hunting quests to create and add to sql.// Minimum and Maximum amount of different monsters to be used as an objective..min_hunting_objective = 1;.max_hunting_objective = 5; // Note - This can not be higher than the number of objectives listed in your sql table. So if your sql table only supports 3, this can be no higher than 3.// Minimum and Maximum amount to be killed for each objective..min_hunting_amount = 5;.max_hunting_amount = 20;// Bonus, a custom command that when used, will attempt to create a (.hunting_generate) more quests and add them to the database.bindatcmd "huntgen", strnpcinfo(3)+"::OnHuntingCreate";end;}
It's untested, but if it works, it should generate 3 hunting quests, with random amount of 1-5 different monsters to hunt, ranging from 5-20 of each to kill. And place them into a sql database.
anticlimax18 reacted to this -
-
SRC modifications involving clif.c and clif.h deal with how the client interprets these sort of things. You'd need to manipulate what the packet is actually sending. You might also possibly need to hex the client as well, but I'm not too sure, nor am I capable of doing this.
-
You could use, Annieruru's getmemberaid command. It can return all the AID's of users within X1,Y1,X2,Y2 range. So if you were to specify, all users with in 9 cells in any direction starting from the unit. You could have it just randomly choose 1 of those or make it do something else based on that information.
Also, you can use a script to make the mob walk dynamically to it's location. It'd be pretty much checking the unit's location every X seconds, and reroute accordingly mid walk, thus eliminating the need to actually set predefined points into an array and making it travel there and reroute to the next predetermined point until it reaches it's destination.
-
Okay, well I thought about various ways to get this to work, but sadly the only way to get it to work is through src modifications ( best way ) or src + scripts ( works, but wouldn't recommend ).
Fastest, but also buggy method:
1. Increase party share range to 30 levels in party.conf
2. Edit party.conf and turn share bonus to +0%.
3. Through script you can make it so players who are in the party need to be within share range of the highest member and will only receive exp based on that.
a. If highest member is level 79 then people level 49-79 can receive exp in the party.
b. If highest member is level 80+ then only those who are within 1-10 levels may receive exp in the party.
Known issues:
1. Player who kills the monster may receive 1-2% more or less exp from the monster.
2. Player's who are out of share range, may receive or lose 1-2% of the killed monster experience.
This is because of how integers work in hercules, there is no decimal everything is whole numbers rounded down.
Best way:
Modify src to fit exactly what you want. More difficult, but definitely better.
-
Just use the NEMO client patcher. It's by far the best, easiest and fastest way to make a working client for any server. http://herc.ws/board/topic/2905-nemo-client-patcher/
-
Well, my information was off by a long shot xD
-
If it needs to walk then you have to make a small algorithm for it. So that it will walk to X recalculate route, walk to Y, recalculate route and continue in this pattern until it reaches it's destination.
Otherwise, you could just use unitwarp if the method of arrival doesn't matter so long as they get there.
hunter4565 reacted to this -
Currently not possible.
probably no ... there is currently no known way to add mapflags through plugin
from this topic: http://herc.ws/board/topic/4830-noitem-mapflag/?p=42296
-
File Name: Instance Check Commands
File Submitter: GmOcean
File Submitted: 07 Nov 2014
File Category: Plugins
Additional Instance Check Commands to go along with the existing instance_check_party.
Commands:
*instance_check_guild(<guild_id>{,<amount>{,<min>{,<max>}}});This function checks if a guild meets certain requirements, returning 1 ifall conditions are met and 0 otherwise. it will only check online characters.amount - number of online guild members (default is 1).min - minimum level of all characters in the guild (default is 1).max - maximum level of all characters int he guild (default is max level in conf).Example:if( instance_check_guild(getcharid(2), 2, 1, 150) ){ mes "Your guild meets the Memorial Dungeon requirements.", mes "All online members are between levels 1-150 and at least two are online."; close;} else { mes "Sorry, your guild does not meet requirements."; close;}
*instance_check_ready(<IOT_TYPE>,<owner_id>{,amount{,min{,max}}});This function checks if the Char, Party, Guild, etc... meets certain requirements, returning 1 ifall conditions are met and 0 otherwise. It will only check online characters.IOT_TYPE: IOT_NONE - Not sure what this is, but will return 1 regardless of settings due to it being unknown. IOT_CHAR - Character ( Will only check for min or max level. Amount doesn't matter since only 1 character can enter IOT_CHAR instance ). IOT_PARTY - Party IOT_GUILD - Guildamount - number of online party members (default is 1).min - minimum level of all characters in the party (default is 1).max - maximum level of all characters in the party (default is max level in conf).Example:if( instance_check_ready(IOT_CHAR, getcharid(0), 1, 75) ){ mes "The player has met all the requirements to enter the instance.", mes "The player is at least level 75 and is online."; close;} else { mes "The player does not meet all the requirements or is offline."; close;}Example 2:if( instance_check_ready(IOT_PARTY, getcharid(1), 5, 10, 50) ){ mes "The party meets all the requirements to enter the instance.", mes "All online members are between the levels 10-50 and at least 5 members are online."; close;} else { mes "Sorry, your party does not meet all the requirements."; close;}Example 3:if( instance_check_ready(IOT_GUILD, getcharid(2), 36, 140, 150) ){ mes "The guild meets all the requirements to enter the instance."; mes "All online members are between the levels 140-150 and at least 36 of them are online."; close;} else { mes "Sorry, your guild does not meet the requirements."; close;}
[Credits: malufett for providing the base for which these commands were derived from].
-
While, I don't feel that RO has died or failed. I do agree with a few of the points made. Also, RO2 I hated it, tried it, didn't like it, deleted it. End of story there.
But even now I can't bring myself to play RO as I used to back during subscription days when it was first released, before there was even a single 99 player.
However, I do find quite a bit of joy in creating scripts and the like for ragnarok. Perhaps I've just moved on from playing to creating !! Call it my feeble attempt at trying to bring to RO what, in my opinion should have been there to begin with.
-
@1 - By default initnpctimer does not have a player attached so you can just use that if you choose to.
@2 -
TRUNCATE TABLE `table_name`
is used when you want to delete all the data from the given table, without deleting the table from the schema.
You shouldn't have any issues of table mix ups, since you can't have the same table name in the same schema.
So, if `votegoal` isn't the table you want to TRUNCATE, then perhaps a different table is what you need to do?
Additionally, if you're having issues, where `votegoal` is the name of a table inside 2 different schemas, and this is the problem, you should be able to specify which schema to truncate from:
query_sql("TRUNCATE database.schema `table_name`");
-
Okay, so when I made this command in script.c originally, it worked fine. In fact, it's just a clone of another command except for a few things.
This particular warning/error i'm receiving is part of the cloned code.
While in script.c there is no error, the command works perfectly fine. However when copy+pasting the code to plugin system. This is the warning/errors I am forced to face:
warning C4018: '<' : signed/unsigned mismatchwarning C4018: '>' : signed/unsigned mismatch
Now, I managed to solve this by simply changing int to int16. But, in script.c it's just a normal int.
Is there a reason that the plugin system picks this up but not the main files when I compile it? Also, I'm compiling in Debug mode so this should be seen. Even when compiling in release mode this isn't found.
-
This is untested, but it should do what you want. All you need to do, is set the array with the castle names, and it will continue to rotate the castle after each WoE.
The only thing is, you can't change it from in-game. Meaning GMs cannot change it at will. This is to prevent conflicts when a guild is inside of the guild dungeon, and a GM changes castle's. Resulting in possible abuse.
Additionally, this script does not limit access to a castle.
All this does is change owner ship of Castle 1 -> Castle 2, Castle 2 -> Castle 3, etc.... And loop back over once it reaches the end.
You need to manage which castle's are available during WoE in a seperate script.
How this script works:
1. Setup script by editing the arrays.
2. After each WoE the castle will rotate. ( Transfer all data from Castle 1 -> Castle 2 ).
- script castle_rotation -1,{OnInit:setarray .castle$[0],"prtg_cas01", // 1st Edition WoE "payg_cas01", "gefg_cas01", "aldg_cas01", "prtg_cas02", "payg_cas02", "gefg_cas02", "aldg_cas02"; setarray .castle2$[0],""; // 2nd Edition WoEend;// Has to be set to AgitEnd or else guild will be kicked out upon changing owner ship of castle.// Therefore after WoE has ended in 1 Castle, the Guild will own the castle NEXT in line.// Example: WoE is in prtg_cas01. It ends. Winning Guild now owns, payg_cas01.// Afterwards, guild should go to that castle to make changes ( investments, etc... )OnAgitEnd:callfunc("rotate_castle", .castle$[$rotation], ( (.castle$[($rotation + 1)] == "")? .castle$[0]:.castle$[($rotation + 1)] ) );$rotation ++;if( .castle$[($rotation + 1)] == "" ){ $rotation = 0;}end;OnAgitEnd2:callfunc("rotate_castle", .castle2$[$rotation], ( (.castle2$[($rotation + 1)] == "")? .castle2$[0]:.castle2$[($rotation + 1)] ) );$rotation ++;if( .castle2$[($rotation + 1)] == "" ){ $rotation = 0;}end;}function script rotate_castle {.@i = 18;while( .@i > 1 ){// Transfer data from Castle 1 -> Castle 2 setcastledata( getarg(1), .@i, getcastledata( getarg(0), .@i) );// Erase Data from Castle 1 after transfering it to Castle 2 setcastledata( getarg(0), .@i, 0 );.@i--;}return 0;}
-
I see. Well, that isn't too bad, guess it would make sense I can't just hook into a function like that.
-
So, what I want to know how to do is, hook into certain parts of code where it does has a switch(case:).
How would I do that if it's even possible. Or do I have to just copy paste all of the code into a plugin, and add my custom code as well, so that it completely overrides it?
-
Updated~!!
Added a Scripting Techniques section, and filled it with a few things not much. Do note, that they are not intended to be used in public scripts it's purely for private use only. Since they can be hard to read at times.
Also, another script guide using bindatcmd. The script is finished as is, but will be expanded on in future parts, so marking incomplete for now.
Edit:
Custom Atcommand @buff - Complete ( 2 Parts ).
-
Well, using NEMO's Patcher you can restore old login on new clients to bypass the use of a launcher. But, i'm not sure if it supports clients this new, it may need to be updated assuming packet's were changed around.
-
What I'm requesting, is to make quest_db a sql table. So that the server will create the db from the SQL table listings, should I choose to enable that. Same way itemdb works with sql.
The reason, is this would allow for use of custom commands to " create " quests and add it to the db, as well as modify existing quests from ingame via an npc or otherwise.
-
No problem. It's something that needed to be done anyways. We should be trying to actively provide awareness to projects that will be a benefit to the RO community. So this can be my contribution to such a cause. =P
[Request Support] Player Customized Quest Script + SQL Track [ALMOST COMPLETE]
in Script Requests
Posted
While, I don't quite like your " tone " depicted with your choice of words, I have commented it. * note - again this hasn't been tested *
This won't help do everything you listed, but it will help give you an idea of how to generate quests and add them to sql.