Jump to content

Gouki

Members
  • Posts

    241
  • Joined

  • Last visited

  • Days Won

    1

Posts posted by Gouki

  1. If you were to buy a hosting, what do you consider based from your experience? What is your go to options/settings?

    Ofcourse Dedicated is better but...
    CPU: AMD / INTEL XEON / INTEL I Series ?
    CORES/GHz: ?
    Memory: ?
    Public Bandwidth: Does this matter? ex. 500mbps/unmetered enough?

    I know most developers would say, rAthena could run on the most cheapest VPS. But, what I'm looking for is your experiences where you had the most stable connection even reaching 500+ people on the server.
    I had experiences, owning a Dedicated Game Server in OVH and still gives Latency issues where in time, when your character walks on a straight path you'd notice it to turn back once in a while. (not sure if this is server issue tho)

    Share your go to Hosting Provider and dedicated server specifications if you are expecting a high volume of people on your server (500 - 1,000) , better if it's direct company like OVH, Digital Ocean, ETC.. THANK YOU!

  2. Hi I've been working on this NPC, and I find it promising and handy for a loot converter, I tried modifying the script to accept but failed.

    Can anyone help me modify this script to accept Misc or Consumable items instead of only just Weapon and Armor?

     

    // https://irowiki.org/wiki/Ben_Recycle
    
    -	shop	ben_recycle_shop	-1,909:-1
    
    payon,111,117,4	script	Ben Recycler	2_M_OLDBLSMITH,{
    	function func_GetItemName;
    	function func_AddItem;
    	
    	mes "[Equipment Recycler]";
    	mes "Hi, I can convert certain equipment into ores.";
    	mes "Would you give it a try?";
    	next;
    	if (select("Convert", "Information") == 2) {
    		for (.@i = 0; .@i < .size; .@i++) {
    			mes func_GetItemName(.nameid[.@i]);
    			if (.amount1[.@i] > 0 && .nameid1[.@i] > 0)
    				mes " ~ "+F_InsertComma(.amount1[.@i])+"x "+func_GetItemName(.nameid1[.@i]);
    			if (.amount2[.@i] > 0 && .nameid2[.@i] > 0)
    				mes " ~ "+F_InsertComma(.amount2[.@i])+"x "+func_GetItemName(.nameid2[.@i]);
    			mes " ";
    		}
    		next;
    	}
    	if (.shop_npc$ != "") {
    		mes "[Equipment Recycler]";
    		mes "Place all the equipments you wish to convert into ores.";
    		close2;
    		npcshopattach .shop_npc$, 1;
    		callshop .shop_npc$, 2;
    		end;
    	}
    	else {
    		for (.@i = 0; .@i < .size; .@i++)
    			.@menu$ = .@menu$ + func_GetItemName(.nameid[.@i]) + ":";
    		.@i = select(.@menu$) - 1;
    		if (countitem(.nameid[.@i])) {
    			delitem .nameid[.@i], 1;
    			mes "[Equipment Recycler]";
    			mes "Exchanged "+func_GetItemName(.nameid[.@i])+":";
    			if (.nameid1[.@i] > 0 && .amount1[.@i] > 0) {
    				mes " ~ "+F_InsertComma(.amount1[.@i])+"x "+func_GetItemName(.nameid1[.@i]);
    				getitem .nameid1[.@i], .amount1[.@i];
    			}
    			if (.nameid2[.@i] > 0 && .amount2[.@i] > 0) {
    				mes " ~ "+F_InsertComma(.amount2[.@i])+"x "+func_GetItemName(.nameid2[.@i]);
    				getitem .nameid2[.@i], .amount2[.@i];
    			}
    		}
    		else {
    			mes "[Equipment Recycler]";
    			mes "you dont have "+func_GetItemName(.nameid[.@i]);
    		}
    	}
    	close;
    	
    	OnSellItem:
    		.@sold_nameid_size = getarraysize(@sold_nameid);
    		for (.@i = 0; .@i < .@sold_nameid_size && !.@fail; .@i++) {
    			for (.@x = 0; .@x < .size && !.@fail; .@x++) {
    				if (.nameid[.@x] == @sold_nameid[.@i]) {
    					if (!checkweight(.nameid1[.@x], .amount1[.@x])) {
    						mes "Exchange stopped, you're overweight.";
    						.@fail++;
    					}
    					else {
    						.@total++;
    						delitem2(@sold_nameid[.@i], @sold_quantity[.@i], @sold_identify[.@i], @sold_refine[.@i], @sold_attribute[.@i], @sold_card1[.@i], @sold_card2[.@i], @sold_card3[.@i], @sold_card4[.@i]);
    						mes "Exchanged "+func_GetItemName(.nameid[.@x])+":";
    						if (.nameid1[.@x] > 0 && .amount1[.@x] > 0) {
    							mes " ~ "+F_InsertComma(.amount1[.@x])+"x "+func_GetItemName(.nameid1[.@x]);
    							getitem .nameid1[.@x], .amount1[.@x];
    						}
    						if (.nameid2[.@x] > 0 && .amount2[.@x] > 0) {
    							mes " ~ "+F_InsertComma(.amount2[.@x])+"x "+func_GetItemName(.nameid2[.@x]);
    							getitem .nameid2[.@x], .amount2[.@x];
    						}
    						mes " ";
    					}
    				}
    			}
    			if (.@i && .@i % 10 == 0) sleep2 1;
    		}
    		mes "Exchanged "+.@total+" item(s).";
    		close2;
    		npcshopattach .shop_npc$, 0;
    		end;
    	
    	function	func_GetItemName	{
    		.@itemid = getarg(0, 0);
    		.@itemslot = getitemslots(.@itemid);
    		.@item_name$ = getitemname(.@itemid);
    		.@itemtype = getiteminfo(.@itemid, 2);
    		if (.@itemslot || .@itemtype == IT_WEAPON || .@itemtype == IT_ARMOR)
    			.@item_name$ = .@item_name$ + " ["+.@itemslot+"]";
    		return .@item_name$;
    	}
    	
    	function	func_AddItem	{
    		.@nameid = getarg(0, 0);
    		.@nameid1 = getarg(1, 0);
    		.@amount1 = getarg(2, 0);
    		//.@nameid2 = getarg(3, 0);
    		//.@amount2 = getarg(4, 0);
    		
    		if (.@nameid > 0 
    			&& .@nameid1 > 0 && .@amount1 > 0
    			//&& .@nameid2 > 0 && .@amount2 > 0 
    		) {
    			.nameid[.size] = .@nameid;
    			.nameid1[.size] = .@nameid1;
    			.amount1[.size] = .@amount1;
    			//.nameid2[.size] = .@nameid2;
    			//.amount2[.size] = .@amount2;
    			.size++;
    		}
    	}
    	
    	OnInit:
    		// if enable shop UI (only work if items can sell to npc shop)
    		.shop_npc$ = "ben_recycle_shop";
    		
    		// func_AddItem(<equipment_id>, <item1>, <amount1>, <item2>, <amount2>);
    		
    		// WEAPONS
    		func_AddItem(1116, 40903, 3);
    		//func_AddItem(1158, 984, 3, 757, 2);
    		//func_AddItem(1553, 984, 2, 757, 3);
    		
    		// ARMORS
    		//func_AddItem(2313, 985, 2, 757, 2);
    		//func_AddItem(2326, 985, 3, 757, 3);
    		end;
    }

     

  3. Hi all,

    Is it possible to spawn NPC around the player after killing a monster? or spawn a NPC around the monster where it was killed?

     


    Update: I found a script..

    The script..

    -	script	Main NPC	-1,{
    	end;
    
    OnNPCKillEvent:
    	if (.state != 1)
    		end;
    	.@inlist = inarray(.moblist[0], killedrid);
    	if (.@inlist == -1)
    		end;
    	.@npcid = getelementofarray(getvariableofnpc(.tombid, "TheTomb"), .@inlist);
    	debugmes "npcid: "+.@npcid;
    	getunitdata(killedgid, .@md);
    	setunitdata(.@npcid, UNPC_MAPID, .@md[UMOB_MAPID]);
    	setunitdata(.@npcid, UNPC_X, .@md[UMOB_X]);
    	setunitdata(.@npcid, UNPC_Y, .@md[UMOB_Y]);
    	setunitdata(.@npcid, UNPC_LOOKDIR, 0);
    	end;
    
    OnInit:
    	setarray .moblist[0], 1002, 1003, 1004, 1005;
    	
    	.@moblistsize = getarraysize(.moblist);
    	.@tombcount = getvariableofnpc(.tombcount, "TheTomb");
    	if (.@moblistsize < .@tombcount) {
    		debugmes "The Tomb count isn't match with the mob count in list";
    		debugmes "Size of Mob List: "+.@moblistsize+", NPC Tomb Count: "+.@tombcount;
    		end;
    	}
    	.state = 1;
    	end;
    }
    
    -	script	TheTomb	-1,{
    	end;
    	
    OnInit:
    	if (strnpcinfo(2) == "")
    		end;
    	.tombcount++;
    	.tombid[.tombcount-1] = getnpcid(0);
    	end;
    
    }
    
    prontera,0,0,0	duplicate(TheTomb)	Tomb#1	112
    prontera,0,0,0	duplicate(TheTomb)	Tomb#2	112
    prontera,0,0,0	duplicate(TheTomb)	Tomb#3	112
    prontera,0,0,0	duplicate(TheTomb)	Tomb#4	112

     

    This is workable, however, I need to or more Tombs (NPC). I have managed to move the Tomb on a different location by editing the coordinates of UMOB. But I'm having a hard time adding another Tomb(NPC). the 2nd Tomb should be on a different location as the first one. Does anyone know how to add a 2nd Tomb by editing this script above?

     

  4. Items
    -----
    You can refer to items by using HTML-like links to certain items:
    
    	<ITEMLINK>Display Name<INFO>Item ID</INFO></ITEMLINK>
    
    Where <Display Name> is the name that will be displayed for your link and
    <Item ID> being the ID of the item you want to link to when clicked.
    
    In 2015 the tag name was changed to <ITEM> resulting in the following syntax:
    
    	<ITEM>Display Name<INFO>Item ID</INFO></ITEM>
    
    The following sample will open a preview window for Red Potion:
    
    	mes "Did you ever consume a <ITEMLINK>Red Potion<INFO>501</INFO></ITEMLINK>?";
    	// Or in 2015:
    	mes "Did you ever consume a <ITEM>Red Potion<INFO>501</INFO></ITEM>?";
    
    NOTE: Be aware that item links are rendered incorrectly in 2015+ clients at the moment.


    I'm currently using 20180621a, when the item link is clicked, the client automatically crashes. I'm using the <ITEM>Display Name<INFO>Item ID</INFO></ITEM> format. The other format doesn't work for my client.

  5. 1 hour ago, Tokei said:

    It will affect your server load, yes. You would need to add a restriction in the source such as:
     

    
    	if (src && src->type == BL_PC && bl->type == BL_MOB && damage > 0) {
    		struct mob_data *md = (struct mob_data *)bl;
    		
    		if (md->id == 1002) {
    			mapreg_setreg(reference_uid(add_str("$@attacked_mid"), 0), md->id);
    			mapreg_setreg(reference_uid(add_str("$@attacked_gid"), 0), md->bl.id);
    			npc_event_do_id("MyNPC::OnEvent", src->id);
    		}
    	}

    That on its own would be more reasonable, but if you have... I don't know, 10 people attacking the mob with 193 aspd, I'd be concerned. You'd probably want to do it all in the source instead, or at the very least put the chance of drop in the source. Something like...

    
    	if (src && src->type == BL_PC && bl->type == BL_MOB && damage > 0) {
    		struct mob_data *md = (struct mob_data *)bl;
    		struct map_session_data *sd = (struct map_session_data *)src;
    		
    		if (md->id == 1002 && (rnd() % 100) < 5) {	// 5% chance
    			struct item it;
    			t_itemid nameid = 501;
    			int flag;
    			
    			memset(&it,0,sizeof(it));
    			it.nameid = nameid;
    			it.identify = 1;
    			it.bound = BOUND_NONE;
    			
    			// Assuming it is not a pet egg, you can skip some checks. Up to you at this point.
    			if ((flag = pc_additem(sd, &it, 1, LOG_TYPE_SCRIPT))) {
    				clif_additem(sd, 0, 0, flag);
    			}
    		}
    	}

     

    damn.. I really appreciate the effort @Tokei, I'll try everything out on my end. have a great day ahead!

  6. Just now, Tokei said:

    Personally though, I'd say you should make a yaml conf file where you define drop groups with a chance, then assign a mob to a drop group in your mob_db.yml file instead. It's more work, but it's also much more effecient than running a script. Then again, that requires more source knowledge I suppose.

    that would be correct. yaml is just new to me still so I think I'll stick with the script.

    However, question.. as long as other monsters are not included on the "case", they won't be triggered right? what I mean is that it won't affect the server load if you attack other monsters?

    Thank you so much for the clarification and the assistance.

  7. 1 hour ago, Tokei said:

    It's possible, but it's also... very intensive for your server and I would highly recommend against it.

    In battle.cpp, in battle_calc_damage, add the NPC call:

    
    	if (bl->type == BL_PC) {
    		npc_event_do_id("MyNPC::OnEvent", bl->id);
    	}

    And with the matching script:

    
    -	script	MyNPC	-1,{
    	end;
    OnEvent:
    	//callfunc("F_Function");
    	dispbottom "You have attacked.";
    	end;
    }

     

    It would be much better to add code in the source for what you want to do instead.

    This script would be on a script generated monster spawn and not for all monster wide. Would there be a workaround for a script based structure without a source mod?

    I'm also thinking of OnTouch behavior, however, there would be no stopping because for the callfunc to work it must be on a loop.

    The end goal is while you are attacking (every hit), you get a chance to obtain certain item by chance.


     

  8. 15 hours ago, pandabro said:

    "Own Land Protector (Defensive) when removed by another players Land Protector (Offensive). Magic will still not hit you.  - Not fixed by script" 

    Will this be fixed? 

    He already messaged me and it is out of the scope of Ganbantein + Land Protector. So, it will not be fixed on this diff.

    Addition, he mentioned to do another paid diff on that one, but no timeline yet on when it'll be released.

  9. All test below was done when an AoE Skill (SG, MS) is casted on the Land Protector.

    Fixed by script
    - Own Land Protector when removed by your own Violent Gale, Deluge, or Volcano. Magic now will hit you
    - Own Land Protector when removed by Ganbantein. Magic now will hit you

    Not yet fixed by script
    - Own Land Protector (Defensive) when removed by another players Land Protector (Offensive). Magic will still not hit you.  - Not fixed by script

    What I noticed here: When the Offensive Land Protector (by other player) is casted on top of another Land Protector, the AoE skills casted prior to that Land Protector also gets removed. this does not happen on your fix when the own player cancels his Land protector or either a Ganbantein is casted on the Land Protector.

    One simple way to check it is to turn on your effects, and when the Offensive Land Protector is casted, the animation of either Storm Gust and Meteor Storm will stop, unlike on the other two, the animation still continues even when the Land Protector gets turned off, or Ganbantein creates a hole on the Land Protector and the player now gets hit.
     

×
×
  • Create New...