GmOcean
Community Contributors-
Content Count
371 -
Joined
-
Last visited
-
Days Won
8
Content Type
Profiles
Forums
Downloads
Staff Applications
Calendar
Everything posted by GmOcean
-
O.o that is weird. But glad it works. If theres anything else regarding this let me know.
-
Hmm, since paladin's were designed around being a supportive/tank class. I'd suggest their heal amount being determined by amount of player's in party as an additional argument. Regular Heal formula + 100 * amount of party members = Crusader heal amount. By default that'd be an increased 1200 heal since I believe 12 party members are by default so meh.
-
That is part of the client as far as I know. If you want to disable it ( not make it show up ). Then you can do a very tedious work around, but I wouldn't recommend it as it's VERY annoying to do. What you'd have to do is basically make custom jobs in a sense. You'd be making these jobs with the 3rd class sprites, 3rd class skills + 2nd class skills and then making the client think they are 2nd classes. This way you'd still get to keep the benefit of going: Rebirth Novice -> High Class -> Trans Class -> 3rd Class. Since it'd have the skills of the trans, but only appear in the 2nd class window. Next you'd need to edit the statuspoint db file so that these classes get the appropriate status points for their respective class. Next you'd need to create a custom job changer. This job changer would do the following: 1. Copy player's Trans skills and skill level. 2. Change Job into custom 3rd classes we created above. 3. Give those skills to the player permanently. Then you'd need to create a custom stat/skillpoint reseter ( if your using one ). This reseter would do the following: 1. Reset Status points like normal. 2. Reset skill points AND THEN subtract the skill points needed to get all the trans skills to the level's they were at. Then lastly, you'd need to either make the script for giving them skills on an infiniteloop OR edit several src files to NOT do a skill-reset upon status point update, change map, unequip/re-equip, etc.... So yeah, like I said, not worth it. Just stick with the 3rd class window =P
-
Here, this is done using bindatcmd. ( @sameip ) It displays in this format: ---------------- List of Same IP User -------------------------------------- Prontera ----------------------IP Address: 127.0.0.1Account ID: 2000001, 2000002, 2000003Character Names: Name1, Name2, Name3IP Address: 192.168.1.1Account ID: 2000004, 2000011Character Names: Name4, Name11etc... It won't show duplicate account ids. Meaning, it will only show 1 IP address and then all the account ids using that IP address and then the names of those characters currently online. So if Player 1 has same IP address as Player2. And Player3 has same IP address as Player 1. It will only show 1 entry to make it neater. - script at_sameip -1,{OnInit:bindatcmd "sameip",strnpcinfo(3)+"::OnAtSameIP";//,99,99,0; // 0 = No log, 1 = Log usageend;OnAtSameIP:.@size = query_sql("SELECT `account_id` FROM `char` WHERE `online` = '1' AND `last_map` = '"+ strcharinfo(3) +"'",.@acct_id);.@size2 = query_sql("SELECT `account_id`, `last_ip` FROM `login` WHERE `account_id` != '1'", .@aid, .@ip$);while( .@a < .@size ) { for( .@i = 0; .@i < getarraysize(.@aid); .@i++ ) { if( .@aid[.@i] == .@acct_id[.@a] ) { .@tempaid$[.@a] = ""+ .@aid[.@i] +""; .@tempaip$[.@a] = .@ip$[.@i]; } } .@a++;}.@size3 = getarraysize(.@tempaid$);while( .@c != .@size3 ) { for( .@i = 0; .@i < getarraysize( .@usedaids$ ); .@i++ ) { if( .@usedaids$[.@i] == .@tempaid$[.@c] ) { //Account ID already in array. .@used = 1; } } if( !.@used ) { .@usedaids$[( getarraysize( .@usedaids$ ) + 1 )] = .@tempaid$[.@c]; .@duplicateaid$[.@c] = "Account IDs: "+ .@tempaid$[.@c] +""; .@duplicaterid2name$[.@c] = "Character Names: "+ rid2name( atoi( .@tempaid$[.@c] ) ) +""; .@duplicateaip$[.@c] = "IP Address: "+ .@tempaip$[.@c] +""; for( .@i = 0; .@i < getarraysize( .@tempaid$ ); .@i++ ) { if( .@tempaip$[.@c] == .@tempaip$[.@i] && .@tempaid$[.@c] != .@tempaid$[.@i] ) { .@duplicateaid$[.@c] = .@duplicateaid$[.@c] +", "+ .@tempaid$[.@i] +""; .@duplicaterid2name$[.@c] = .@duplicaterid2name$[.@c] +", "+ rid2name( atoi( .@tempaid$[.@i] ) ) +""; .@usedaids$[( getarraysize( .@usedaids$ ) + 1 )] = .@tempaid$[.@i]; } } } .@used = 0; .@c++; }dispbottom "---------------- List of Same IP User ----------------";dispbottom "---------------------- "+ setchar( strcharinfo(3), strtoupper(charat(strcharinfo(3),0)), 0 ) +" ----------------------";for( .@i = 0; .@i < getarraysize(.@duplicateaid$); .@i++ ) { if( .@duplicateaid$[.@i] != "" ) { dispbottom " "; dispbottom .@duplicateaip$[.@i]; dispbottom .@duplicateaid$[.@i]; dispbottom .@duplicaterid2name$[.@i]; } }end;} Enjoy D:
-
OH LOL, i hadn't realized I clicked upload file... was blindly clicking, while just thinking upload new file lmao. My appologies, I'll keep THIS one. Sorry about that @.@;
-
I updated the files to v0.7 which as a number of changes and additions. It will be available as soon as the upload gets approved by someone with POWER lol.
-
Is there a way to make a character move like using a skill?
GmOcean replied to Echoes's question in Script Support
Okay, well this is all you need to do: 1. Open up script.c & Find: BUILDIN(mes 2. Above that add in: // PickUp Item Effect// pickupitem();BUILDIN(pickupitem) { struct block_list tbl; TBL_PC* sd = script->rid2sd(st); if( sd == NULL ) return true; tbl.id = 0; clif->takeitem(&sd->bl,&tbl); return true;} 3. Find: BUILDIN_DEF(mes 4. Above that add: BUILDIN_DEF(pickupitem,""), Save & Recompile. Then make a script that tells the player to use it. *Note - Player must be attached to the script for it to work (talking to it or otherwise).* Example NPC: prontera,150,170,4 script npc_name 123,{mes "I command you to pick up an item !!";pickupitem;close;} In that example as soon as they click the NPC, a MES window will pop up and they will bend over to pick up an item (wont get an item though just the animation). -
Is there a way to make a character move like using a skill?
GmOcean replied to Echoes's question in Script Support
What your looking for is the animation of looting items off of the floor. It's a standard animation each character has and needs, you just almost never see it anymore because everyone uses @autoloot. clif->takeitem(&sd->bl,&tbl); You just need a command to send that clif packet and it'll do the animation. -
Okay, so adding items via itemdb.conf is really easy now, since you essentially only need to input 3 fields to get an item to exist in game. However, on the SQL side for those of us who use it, you still need to add all the information or it'll be buggy and could cause issues. Since default is either NULL or 0. #1. I suggest we update this to take on the same parameters as itemdb.conf when not filling them in. It only makes sense in my opinion. (Yes I know I can easily do this myself by editing the main.sql file. But this is a suggestion so that we won't have to in the future). #2. of the suggestion is about the inherit feature. While looking in itemdb.c you'll notice that it does some PRE-checks before adding the data to the *db. It reads the sql entries -> checks to see if it's valid -> changes information so that it is valid in the instance where it is incorrect. /** * Processes one itemdb entry from the sql backend, loading and inserting it * into the item database. * * @param *handle MySQL connection handle. It is expected to have data * available (i.e. already queried) and it won't be freed (it * is care of the caller to do so) * @param n Ordinal number of the entry, to be displayed in case of * validation errors. * @param *source Source of the entry (table name), to be displayed in case of * validation errors. * @return Nameid of the validated entry, or 0 in case of failure. */int itemdb_readdb_sql_sub(Sql *handle, int n, const char *source) { struct item_data id = { 0 }; char *data = NULL; /* * `id` smallint(5) unsigned NOT NULL DEFAULT '0' * `name_english` varchar(50) NOT NULL DEFAULT '' * `name_japanese` varchar(50) NOT NULL DEFAULT '' * `type` tinyint(2) unsigned NOT NULL DEFAULT '0' * `price_buy` mediumint(10) DEFAULT NULL * `price_sell` mediumint(10) DEFAULT NULL * `weight` smallint(5) unsigned DEFAULT NULL * `atk` smallint(5) unsigned DEFAULT NULL * `matk` smallint(5) unsigned DEFAULT NULL * `defence` smallint(5) unsigned DEFAULT NULL * `range` tinyint(2) unsigned DEFAULT NULL * `slots` tinyint(2) unsigned DEFAULT NULL * `equip_jobs` int(12) unsigned DEFAULT NULL * `equip_upper` tinyint(8) unsigned DEFAULT NULL * `equip_genders` tinyint(2) unsigned DEFAULT NULL * `equip_locations` smallint(4) unsigned DEFAULT NULL * `weapon_level` tinyint(2) unsigned DEFAULT NULL * `equip_level_min` smallint(5) unsigned DEFAULT NULL * `equip_level_max` smallint(5) unsigned DEFAULT NULL * `refineable` tinyint(1) unsigned DEFAULT NULL * `view` smallint(3) unsigned DEFAULT NULL * `bindonequip` tinyint(1) unsigned DEFAULT NULL * `buyingstore` tinyint(1) NOT NULL DEFAULT NULL * `delay` mediumint(9) NOT NULL DEFAULT NULL * `trade_flag` smallint(4) NOT NULL DEFAULT NULL * `trade_group` smallint(4) NOT NULL DEFAULT NULL * `nouse_flag` smallint(4) NOT NULL DEFAULT NULL * `nouse_group` smallint(4) NOT NULL DEFAULT NULL * `stack_amount` mediumint(6) NOT NULL DEFAULT NULL * `stack_flag` smallint(2) NOT NULL DEFAULT NULL * `sprite` mediumint(6) NOT NULL DEFAULT NULL * `script` text * `equip_script` text * `unequip_script` text */ SQL->GetData(handle, 0, &data, NULL); id.nameid = (uint16)atoi(data); SQL->GetData(handle, 1, &data, NULL); safestrncpy(id.name, data, sizeof(id.name)); SQL->GetData(handle, 2, &data, NULL); safestrncpy(id.jname, data, sizeof(id.jname)); SQL->GetData(handle, 3, &data, NULL); id.type = atoi(data); SQL->GetData(handle, 4, &data, NULL); id.value_buy = data ? atoi(data) : -1; // Using invalid price -1 when missing, it'll be validated later SQL->GetData(handle, 5, &data, NULL); id.value_sell = data ? atoi(data) : -1; SQL->GetData(handle, 6, &data, NULL); id.weight = data ? atoi(data) : 0; SQL->GetData(handle, 7, &data, NULL); id.atk = data ? atoi(data) : 0; SQL->GetData(handle, 8, &data, NULL); id.matk = data ? atoi(data) : 0; SQL->GetData(handle, 9, &data, NULL); id.def = data ? atoi(data) : 0; SQL->GetData(handle, 10, &data, NULL); id.range = data ? atoi(data) : 0; SQL->GetData(handle, 11, &data, NULL); id.slot = data ? atoi(data) : 0; SQL->GetData(handle, 12, &data, NULL); itemdb->jobid2mapid(id.class_base, data ? (unsigned int)strtoul(data,NULL,0) : UINT_MAX); SQL->GetData(handle, 13, &data, NULL); id.class_upper = data ? (unsigned int)atoi(data) : ITEMUPPER_ALL; SQL->GetData(handle, 14, &data, NULL); id.sex = data ? atoi(data) : 2; SQL->GetData(handle, 15, &data, NULL); id.equip = data ? atoi(data) : 0; SQL->GetData(handle, 16, &data, NULL); id.wlv = data ? atoi(data) : 0; SQL->GetData(handle, 17, &data, NULL); id.elv = data ? atoi(data) : 0; SQL->GetData(handle, 18, &data, NULL); id.elvmax = data ? atoi(data) : 0; SQL->GetData(handle, 19, &data, NULL); id.flag.no_refine = data && atoi(data) ? 0 : 1; SQL->GetData(handle, 20, &data, NULL); id.look = data ? atoi(data) : 0; SQL->GetData(handle, 21, &data, NULL); id.flag.bindonequip = data && atoi(data) ? 1 : 0; SQL->GetData(handle, 22, &data, NULL); id.flag.buyingstore = data && atoi(data) ? 1 : 0; SQL->GetData(handle, 23, &data, NULL); id.delay = data ? atoi(data) : 0; SQL->GetData(handle, 24, &data, NULL); id.flag.trade_restriction = data ? atoi(data) : ITR_NONE; SQL->GetData(handle, 25, &data, NULL); id.gm_lv_trade_override = data ? atoi(data) : 0; SQL->GetData(handle, 26, &data, NULL); id.item_usage.flag = data ? atoi(data) : INR_NONE; SQL->GetData(handle, 27, &data, NULL); id.item_usage.override = data ? atoi(data) : 0; SQL->GetData(handle, 28, &data, NULL); id.stack.amount = data ? atoi(data) : 0; SQL->GetData(handle, 29, &data, NULL); if (data) { int stack_flag = atoi(data); id.stack.inventory = (stack_flag&1)!=0; id.stack.cart = (stack_flag&2)!=0; id.stack.storage = (stack_flag&4)!=0; id.stack.guildstorage = (stack_flag&8)!=0; } SQL->GetData(handle, 30, &data, NULL); if (data) { id.view_id = atoi(data); if (id.view_id) id.flag.available = 1; } SQL->GetData(handle, 31, &data, NULL); id.script = data && *data ? script->parse(data, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL; SQL->GetData(handle, 32, &data, NULL); id.equip_script = data && *data ? script->parse(data, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL; SQL->GetData(handle, 33, &data, NULL); id.unequip_script = data && *data ? script->parse(data, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL; return itemdb->validate_entry(&id, n, source);} Knowing this we could add an INHERIT column in our sql itemdb entries to allow for the option of making an item inherit that of another item. Which leads to my third suggestion. #3. While inherit is useful in some cases, it's fairly if not vastly limited, since it's a boolean option. Meaning either YES inherit or NO don't inherit. This should be changed to an item_id entry. So that we can specify WHAT item it inherits its information from. That way were not limited to re-making an existing item just to change or add a feature. Example of current inherit: { Id: 501 AegisName: "Red_Potion" Name: "Red Potion" Buy: 1200 Weight: 150 Script: <" itemheal rand(325,405),0; "> Inherit: true}, This will make a red potion inherit all of it's information from itemdb.conf but make it act like a White Potion in terms of buy/sell price, weight and heal power. Example of suggested inherit: { Id: 501 AegisName: "Red_Potion" Name: "Red Potion" Inherit: 504}, This would effectively do the same thing as above should we decide to add it. BUT more importantly, i wouldn't be limited to using an existing item ID. { Id: 32000 AegisName: "New_Potion" Name: "New Potion" Inherit: 504}, Thusly allowing us to add new items in and inherit information without the need to overwrite an item already in existence. ( I'm repeating myself xD ). Naturally this could be applied to the SQL side as well and rightfully should if there aren't any underlying compatibility issues. For those who don't know what I'm talking about in relation to the src here is the section in question: if( (t = libconfig->setting_get_member(it, "Inherit")) && (inherit = libconfig->setting_get_bool(t)) ) { if( !itemdb->exists(id.nameid) ) { ShowWarning("itemdb_readdb_libconfig_sub: Trying to inherit nonexistent item %d, default values will be used instead.n", id.nameid); inherit = false; } else { // Use old entry as default struct item_data *old_entry = itemdb->load(id.nameid); memcpy(&id, old_entry, sizeof(struct item_data)); } } It would be a simple change to: *Note - would also need to change bool inherit = false to int inherit = false if( (inherit = libconfig->setting_lookup_int(it, "Inherit", &i32 )) ) { if( !itemdb->exists(id.nameid) && inherit == 1 || !itemdb->exists(inherit) && inherit != 1 ) { ShowWarning("itemdb_readdb_libconfig_sub: Trying to inherit nonexistent item %d, default values will be used instead.n", inherit); inherit = false; } else { // Use old entry as default if( inherit = 1 ) { struct item_data *old_entry = itemdb->load(id.nameid); memcpy(&id, old_entry, sizeof(struct item_data)); } else { struct item_data *old_entry = itemdb->load(inherit); memcpy(&id, old_entry, sizeof(struct item_data)); } } } From my limited knowledge on the src code ( and coding in general ), this would let it lookup the item specified rather than a boolean option and then use that information as the default, else go to the default paramters given in itemdb.conf
-
In CLIF.C find: /// Request to add an item to the action (CZ_AUCTION_ADD_ITEM)./// 024c <index>.W <count>.Lvoid clif_parse_Auction_setitem(int fd, struct map_session_data *sd){ int idx = RFIFOW(fd,2) - 2; int amount = RFIFOL(fd,4); // Always 1 struct item_data *item; if( !battle_config.feature_auction ) return; if( sd->auction.amount > 0 ) sd->auction.amount = 0; if( idx < 0 || idx >= MAX_INVENTORY ) { ShowWarning("Character %s trying to set invalid item index in auctions.n", sd->status.name); return; } if( amount != 1 || amount > sd->status.inventory[idx].amount ) { // By client, amount is always set to 1. Maybe this is a future implementation. ShowWarning("Character %s trying to set invalid amount in auctions.n", sd->status.name); return; } if( (item = itemdb->exists(sd->status.inventory[idx].nameid)) != NULL && !(item->type == IT_ARMOR || item->type == IT_PETARMOR || item->type == IT_WEAPON || item->type == IT_CARD || item->type == IT_ETC) ) { // Consumable or pets are not allowed clif->auction_setitem(sd->fd, idx, true); return; } if( !pc_can_give_items(sd) || sd->status.inventory[idx].expire_time || !sd->status.inventory[idx].identify || !itemdb_canauction(&sd->status.inventory[idx],pc_get_group_level(sd)) || // Quest Item or something else (sd->status.inventory[idx].bound && !pc_can_give_bound_items(sd)) ) { clif->auction_setitem(sd->fd, idx, true); return; } sd->auction.index = idx; sd->auction.amount = amount; clif->auction_setitem(fd, idx + 2, false);} Change this part: if( (item = itemdb->exists(sd->status.inventory[idx].nameid)) != NULL && !(item->type == IT_ARMOR || item->type == IT_PETARMOR || item->type == IT_WEAPON || item->type == IT_CARD || item->type == IT_ETC) ) { // Consumable or pets are not allowed clif->auction_setitem(sd->fd, idx, true); return; } INTO clif->auction_setitem(sd->fd, idx, true); return; This will allow you to post ALL type of items in the auction. Or SHOULD allow you to. Don't know how the client will act upon doing this, but I do know that I am able to put RedPotions in my auction house so yeah. ( I did not make these changes, I was already able to do it, don't know why D: ). As always make a back-up copy of your src files before making these changes. And don't forget to recompile after making the changes. *Note - This clif packet currently has amount set to 1 by default. Not sure if this can be changed as I currently can't test this. But keep in mind that placing a large stack of consumables may be reduced to just 1 while listed in the auction. This could cause a loss of items or it might just take 1 away. Would be a pain to have to list 100 Ygg berries 1by1.
-
Lol, that makes sense. As for the price[0] i was copy pasting to do it fast since, I didn't wanna get caught at work xD thanks for that.
-
Edit: Okay, I see your problem. I'm sorry, but ATM i'm not able to properly test these things.... You'll just have to continue to use the zeny mode until I can get a working client system setup at my computer at work. Or until I fix my personal comp (work station). Sorry :/
-
Oh sorry lol. I put the parenthesis in the wrong spot... I always do that when using variable? I don't know why, it just looks better that way. I updated my previous post. Should work, but again, untested. Work station still broken T.T
-
This is untested as my work station is down atm. But this should do what you want. Just follow the annotations under OnInit label to make it work with items instead of zeny. When my work station is up and running i'll post an update to allow for a more hybrid version and written in better code ( right now it's all smushed together, and is unnessecarily complicated ). /* =============================================================/* Slot Machine - Triple Slot Machine/* =============================================================/* Version: v0.2a/* v0.1 - Original Script Created./* v0.2 - Added Option for Triple Slot Machine with animations./* v0.2a - Added option for item price instead of zeny.Untested./* =============================================================/* Description/* =============================================================/* This script will allow users to spend zeny for a chance to/* win a prize from the slot machine. Currently there are 2/* versions. First is a Single Slot Machine, where only 1 slot/* is rolled. Second is the Triple Slot machine, where 3 slots/* are rolled. For either version, SUCCESS must be the only/* thing displayed in order to win./* =============================================================/* Created By: GmOcean/* ===========================================================*/prontera,152,176,4 script SlotMachine 563,{switch( .mode ){ case 0: // Single Slot machine mode. mes "Do you want to play a game?","It costs: "+ .price[1] +" "+ (.price[2]?"zeny":""+getitemname(.price[0])+"") +" to play."; if( select("YES:NO") == 2 || Zeny < .price[0] && !.price[2] || ( countitem( .price[0] ) < .price[1] ) && .price[2] ){ close; } while( @menu == 1 ){ if( !.price[2] ){ Zeny -= .price[0]; } else { delitem .price[0],.price[1]; } .@a = rand(1,100); if( .@a < atoi(.1animate$[0]) ){ .@a = 1; } else { .@a = 2; } .@b = 1; while( .@b < atoi(.1animate$[.@a]) ) { cutin .1animate$[3] + .@b,4; sleep2 ( ( atoi(.1animate$[4]) * 1000 ) / atoi(.1animate$[.@a]) ); .@b++; } if( .@a == 1 ){ cutin .1animate$[3] + atoi(.1animate$[.@a]),4; dispbottom "Failed"; } else { cutin .1animate$[3] + atoi(.1animate$[.@a]),4; getitem .1prize[0], .1prize[1]; } if( select("Another Round:I'm done") == 2 || Zeny < .price[0] && !.price[2] || ( countitem( .price[0] ) < .price[1] ) && .price[2] ){ cutin "",255; close; } } end; case 1: // Triple Slot machine mode. mes "Do you want to play a game?","It costs: "+ .price[1] +" "+ (.price[2]?"zeny":""+getitemname(.price[0])+"") +" to play."; if( select("YES:NO") == 2 || Zeny < .price[0] && !.price[2] || countitem( .price[0] ) < .price[1] && .price[2] ){ close; } while( @menu == 1 ){ if( !.price[2] ){ Zeny -= .price[0]; } else { delitem .price[0],.price[1]; } // Slot 1 = 100% Chance for success. (Because I didn't make a fail animation for it. .@2 = rand(1,100); //Rolls dice for Slot 2 .@3 = rand(1,100); //Rolls dice for Slot 3 if( .@2 <= atoi(.3animate$[0]) && .@3 <= atoi(.3animate$[1]) ){ .@a = 8; } else if( .@2 <= atoi(.3animate$[0]) && .@3 > atoi(.3animate$[1]) ){ .@a = 6; } else if( .@2 > atoi(.3animate$[0]) && .@3 <= atoi(.3animate$[1]) ){ .@a = 4; } else { .@a = 2; } .@b = 1; while( .@b < atoi(.3animate$[.@a+1]) ) { cutin .3animate$[.@a] + .@b,4; sleep2 ( ( atoi(.3animate$[10]) * 1000 ) / atoi(.3animate$[.@a+1]) ); .@b++; } cutin .3animate$[.@a] + atoi(.3animate$[.@a+1]),4; if( .@a == 2 ){ getitem .3prize[0], .3prize[1]; } else { dispbottom "Failed"; } if( select("Another Round:I'm done") == 2 || Zeny < .price[1] ){ cutin "",255; close; } } end; }OnInit://[ 0 = Single Slot Machine Mode ]_[ 1 = Triple Slot Machine Mode ].mode = 1;//[0] = Fail Rate//[1] = Fail (Do not change)//[2] = Success (Do not change)//[3] = File Name (Do not change)//[4] = Animation Time (Do not change, for best results )setarray .1animate$[0],"30","29","33","slot_","3";//[0] = Fail Rate "Slot 2"//[1] = Fail Rate "Slot 3"//[2] = SSS (Do not change)//[3] = SSS_Count (Do not change)//[4] = SSF (Do not change)//[5] = SSF_Count (Do not change)//[6] = SFS (Do not change)//[7] = SFS_Count (Do not change)//[8] = SFF (Do not change)//[9] = SFF_Count (Do not change)//[10] = Animation Time (Do not change, for best results )setarray .3animate$[0],"30","30","SSS_","41","SSF_","37","SFS_","41","SFF_","45","3";setarray .1prize[0],501,10;setarray .3prize[0],501,30;// [ 0 = SSM Zeny / Item Req ] | [ 1 = TSM Zeny / Item Amt ] | [ 2 = Enable/Disable Item Requirements ( 0 = Disable, 1 = Enable ).// e.g of zeny mode: setarray .price[0], 100, 300, 0; <--- SSM costs 100z, TSM costs 300z to play.// e.g of item mode: setarray .price[0], 501, 10, 1; <---- SSM & TSM costs 10 RedPotions to play.setarray .price[0],100,300,0;end;}
-
I was using it earlier this week. and it seemed fine. I think i'm using client version 2013-08-07. But i jump around from that and 2014-01-XX (cant remember the EXACT one).
-
AFAIK ragnarok's auction system accepts all item types.
-
I believe there was a client patch released a while ago that disables those messages, since it's in the official client. Coding the 0exp and 0drop wouldn't be that hard to do. Just add it as a permission and change the player's permission until they logout.
-
Need help again :D Black walls appears on the Map
GmOcean replied to kneeeeel's question in Graphics Support
Looks like it may be a lighting issue. Try checking those again., -
Yeah, but any time a player receives damage, the client needs to update that information. By default it uses those clif->hp to do those updates, if I were to add the variable checks to those clif's it would interfere with the proper update because it would push for SP update instead. Also, it's better to use custom Clifs for modifications like this so as to not completely interfere with the way existing code works. Edit: Now that I re-think about it, you could be right about just adding the check to clif->hp, but since creating new clifs doesn't impact the way it works I'll use that since it makes things easier to read when looking at the code as a whole.
-
It'd cause issues down the line with battle.c for use with skills that do HP/SP ratios to calculate damage. And yeah, @showsp just switches the variable. Once this issue of updating properly is fixed, i'll just create a custom state and switch that around so as not to rely on player variables. Also i believe a player's state is reset upon relogging which is what i'd like to have this do without the need of OnPCLoginEvent.
-
I've been asking for assistance quite a bit lately, forgive me xD Okay, let's start off with, I know there currently isn't any packets that support the display of party member's SP bar(blue). So I decided to settle with copying the clif->hpdisplay and making SP versions, to just update the HP with SP status information. This is all done by performing a check of a player's variable and if yes update with SP if no, update with HP. So far it works.... but backwards @.@; What I want it to do is, if a player turns @showsp on. Then the HP bars of his/her party members will be updated with SP information. Then when a party member who has @showsp off, will only see HP bars with HP information. That means, even the HP of the player using @showsp on. But, what I managed to do was this: 1. Player A uses @showsp on. 2. Player B uses @showsp off. 3. Player A uses a skill. 4. Player B see's his HP bar drop. Pressing Alt+Z will also display the same information. (This is the problem. Player B should only see the HP information). 5. Player B uses a skill. 6. Player A doesn't see a change in the bar because Player B isn't showing SP. (Again this is a problem. Player A should see an update because he is requesting to see SP information). I don't know where I went wrong with this patch, but i'll post what changes I made. ( Don't mind the buybacklist clif added in there. It is completely irrelevant to this, and also doesn't interfere with it =P ) showsp.patch
-
This isn't a fix for issues regarding adding items into the game incorrectly, but rather it's a bit of code added in, that creates dummy information for items that just don't exist. For instance creating an item in itemdb2.conf but not adding any information on the client side. This will let the server give you an item, without having a sprite, since it will default to the apple, and call it unknown item and such.
-
Okay, so we all know that if we obtain an item that doesn't exist, it gives us a " dummy " item. However, through all my attempts I was never able to change that information. void create_dummy_data(void){ memset(&itemdb->dummy, 0, sizeof(struct item_data)); itemdb->dummy.nameid=500; itemdb->dummy.weight=1; itemdb->dummy.value_sell=1; itemdb->dummy.type=IT_ETC; //Etc item safestrncpy(itemdb->dummy.name,"UNKNOWN_ITEM",sizeof(itemdb->dummy.name)); safestrncpy(itemdb->dummy.jname,"UNKNOWN_ITEM",sizeof(itemdb->dummy.jname)); itemdb->dummy.view_id=UNKNOWN_ITEM_ID;} essentially, that holds all the information of the dummy item. But even if I change the name of that dummy item, it doesn't update to what I set it as. It either becomes, Apple or Unknown Item. It doesn't even have the _ in its name. So is there something I'm missing from all of this? Or is it hardcoded else where? Because, theoretically configuring this data and all sources that control it's creation, dynamic item creation should be possible. Unless I'm COMPLETELY missing something of importance here. Any thoughts?
-
Well, this program works fine for me. Don't seem to have any of the issues other people are having. I just 2 questions though.... 1. Any idea when you might be feeling upto releasing the packet to change name colors? and 2. If you managed to find those, then perhaps you'd be able to find the one that allows the client to change the color of item names. (The one that happens when using 3-4cards on items, binding items, etc....). Other than that, I love the simplicity this program adds when diffing clients. It was always a hassle having to find the .diff file for your specific client and modify it to only patch certain things. But NEMO makes it 100million times easier. Absolutely love it. Made upgrading my client from 2010 -> 2013 -> 2014 very easy and issue free.
-
Default Kafra already does this. Here is a small sample of when trying to open storage. // Accessing Normal Storage (Skipped if accessing Storage from Guild castle) if (getarg(0) != 2) { // Consume "Free Ticket for Kafra Storage" if available. if (countitem(Cargo_Free_Ticket)) { delitem Cargo_Free_Ticket, 1; } else { if (Zeny < getarg(1)) { mes getarg(3); // Niflheim Specific Message if (getarg(2) == 1) { percentheal -50,-50; mes "^666666Zeeeeeny..."; mes "M-more z-zeny...!"; mes "N-neeed 150... zeny..."; mes "Ergh! T-taking bl-blood~!^000000"; return; } // Standard Message mes "I'm sorry, but you don't"; mes "have enough zeny to use"; mes "the Storage Service. Our"; mes "Storage access fee is "+getarg(1)+" zeny."; return; } Zeny -= getarg(1); if (getarg(2) != 6) RESRVPTS += getarg(1) / 5; } } If you look closely you'll see this: // Consume "Free Ticket for Kafra Storage" if available. if (countitem(Cargo_Free_Ticket)) { delitem Cargo_Free_Ticket, 1; That tells it to take a ticket instead of paying zeny, should they have 1 in their inventory.