#region Pk Arena Guard
case 10021:
if (Request)
{
NpcText("The arena is open. Welcome to challenge other people. The admission fee", Sender);
NpcText("is only 50 silver.If you PK in the arena, you will not gain or lose any", Sender);
NpcText("experience or items equipped,and will get revived at the place you die.The", Sender);
NpcText("Kungfu circle is very dangerous, I suggest you PK in arena.", Sender);
NpcLink("Enter the arena.", 1, Sender);
NpcEndLink("Just passing by.", Sender);
NpcFace(32, Sender);
NpcEnd(Sender);
}
else
{
switch (Cmd)
{
case 1:
if (Sender.Character.Money > 50)
{
Money(-50, Sender);
Sender.Character.X = 50;
Sender.Character.Y = 51;
Sender.Character.Map = 1005;
CommandsHandler.Teleport(Sender);
}
break;
default:
break;
}
}
break;
#endregion
[Npc]
Count=3 // Count of lines
LookFace=33 // FaceLook
Line[1]=(T)Hello~do~you~want~500~silvers? //(T) = Text
Line[2]=(O)Sure // (O) Option = Link will be generated by the system
Line[3]=(OP)No thanks. // Link with nmbr; 255.
[Npc1] // if (LinkBack == 1) // if (Option == 1) for CoEmu/NewestCOServer users.
Count=3
LookFace=33
Line[1]=%add_money=500 // Function must start with %
Line[2]=(T)There~you~go!
Line[3]=(OP)Thanks
Maybe, you can make your more complete. You don't have requirement? Mine looks like this. I never retouch it...
Code:
;********************
;**GardienDeL'Arène**
;********************
[Page0]
Count = 1
Text0 = Vous pouvez entrer dans l'arène en payant 50 argent. Si vous êtes tué, vous ne perdrez pas d'expérience ou d'équipement. Le monde est plein de danger, je vous conseille de vous exercer ici.
Opt0 = Je veux entrer dans l'arène. - 1 : Ça ne m'intéresse pas. - 255
Face0 = 7
[Page1]
Count = 1
Req0 = Money >= 50
Rew0 = Money[-50] & Teleport[1005, 51, 68]
Maybe, you can make your more complete. You don't have requirement? Mine looks like this. I never retouch it...
Code:
;********************
;**GardienDeL'Arène**
;********************
[Page0]
Count = 1
Text0 = Vous pouvez entrer dans l'arène en payant 50 argent. Si vous êtes tué, vous ne perdrez pas d'expérience ou d'équipement. Le monde est plein de danger, je vous conseille de vous exercer ici.
Opt0 = Je veux entrer dans l'arène. - 1 : Ça ne m'intéresse pas. - 255
Face0 = 7
[Page1]
Count = 1
Req0 = Money >= 50
Rew0 = Money[-50] & Teleport[1005, 51, 68]
Thanks for trying to help, we have switched from external to internal instead.
If your going internal i highly suggest not using the one you posted up there.
A while ago i worked on an LOTF based server and customized a bunch of things, i'm not great with C# but did what i could.
Example of TaoistMoon.cs
Code:
using System;
using System.Collections.Generic;
using System.Text;
using BeyondCO.Model;
namespace BeyondCO.NPCScripts
{
public class TaoistMoon : NPCHandler
{
public int getID()
{
return 104813;
}
public void Handle(int option, ref int STAGE, Client client)
{
if (STAGE == 1)
{
Dialog dialog = new Dialog(client);
dialog.AddText("Would you like some free gear?");
dialog.AddOption("Yes");
dialog.AddOption("No");
dialog.Finish();
STAGE++;
}
else if (STAGE == 2)
{
if (option == 1)
{
Dialog dialog = new Dialog(client);
dialog.AddText("Choose your Class");
dialog.AddOption("Warrior");
dialog.AddOption("Archer");
dialog.AddOption("Trojan");
dialog.AddOption("Taoist");
dialog.Finish();
STAGE++;
}
}
else if (STAGE == 3)
{
if (option == 1)
{
client.Command("/job 25");
client.Command("/level 130");
client.Command("/silvers 5000000");
client.Command("/cps 5000000");
client.Command("/item Super ConquestHelmet 12 7 255 13 13");
client.Command("/item Super PhoenixArmor 12 7 255 13 13");
client.Command("/item Super CrystalEarring 12 7 255 13 13");
client.Command("/item Super Blizzard 12 7 255 13 13");
client.Command("/item Super Tornado 12 7 255 13 13");
client.Command("/item Super Thunder 12 7 255 13 13");
client.Command("/item Super ConquestWand 12 7 255 13 13");
}
else if (option == 2)
{
client.Command("/job 45");
client.Command("/level 130");
client.Command("/silvers 5000000");
client.Command("/cps 5000000");
client.Command("/item Super PhoenixJerkin 12 7 255 13 13");
client.Command("/item Super PhoenixHat 12 7 255 13 13");
client.Command("/item Super PhoenixPlume 12 7 255 13 13");
client.Command("/item Super CrystalEarring 12 7 255 13 13");
client.Command("/item Super Tornado 12 7 255 13 13");
client.Command("/item Super Thunder 12 7 255 13 13");
client.Command("/item Super ShadowBow 12 7 255 13 13");
client.Command("/item Super Blizzard 12 7 255 13 13");
}
else if (option == 3)
{
client.Command("/job 15");
client.Command("/level 130");
client.Command("/silvers 5000000");
client.Command("/cps 5000000");
client.Command("/item Super MagicCoronet 12 7 255 13 13");
client.Command("/item Super ConquestArmor 12 7 255 13 13");
client.Command("/item Super CrystalEarring 12 7 255 13 13");
client.Command("/item Super Tornado 12 7 255 13 13");
client.Command("/item Super Thunder 12 7 255 13 13");
client.Command("/item Super BuriedBlade 12 7 255 13 13");
client.Command("/item Super KingsClub 12 7 255 13 13");
client.Command("/item Super KingOfSword 12 7 255 13 13");
client.Command("/item Super Blizzard 12 7 255 13 13");
}
else if (option == 4)
{
client.Command("/job 145");
client.Command("/level 130");
client.Command("/silvers 5000000");
client.Command("/cps 5000000");
client.Command("/item Super UltimateCap 12 7 255 13 13");
client.Command("/item Super PineRobe 12 7 255 13 13");
client.Command("/item Super CrystalEarring 12 7 255 13 13");
client.Command("/item Super Sunshine 12 7 255 13 13");
client.Command("/item Super Lightning 12 7 255 13 13");
client.Command("/item Super KingOfBacksword 12 7 255 13 13");
client.Command("/item Super Blizzard 12 7 255 13 13");
}
}
}
}
}
source for the full project is here: if anyone wants it.
Your calling a new instance everytime a npc is called, that's quite an amount of memory. We're trying to keep the memory usage a bit low, anyway thanks for your advice though.
no, theres only 1 instance to each NPC class. if your talking about the dialog class then yes, but the gc cleans that up. I assume your not a fan of object orientation then.
no, theres only 1 instance to each NPC class. if your talking about the dialog class then yes, but the gc cleans that up. I assume your not a fan of object orientation then.
You should avoid creating unnecessary objects. It is often appropriate to reuse objects. It can be both faster and more stylish. That has nothing to do with being "a fan of object orientation."
You should avoid creating unnecessary objects. It is often appropriate to reuse objects. It can be both faster and more stylish. That has nothing to do with being "a fan of object orientation."
Each NPC class does get reused and is even faster than a switch (which is technically multiple if's and a lot of pointless instructions to get to it's target) by invoking the script straight from a hashtable using the NPC ID not to mention being much neater & structured than stuffing tons of NPC scripts all ugly into 1 huge class. His current way looks exactly how LOTF has it and that lacks serious OOP there are boxed arrays used for almost everything.
The Dialog class gets completely cleaned by the garbage collector automatically, let's say it didn't. the dialog class is worth, roughly 100 bytes? including all the text and options, you would need 10,000 NPC interactions for each 1mb memory leak? which won't happen anyway.
Let's be honest he can do what he wants, but why does everyone have to follow the crowd and whats been done before? especially when they were done poorly. It's almost like you don't know of any other way, i'm just trying to give you a hand and more options. Look at Korvacs his is different, i also remember some other text based script system i think inf wrote awhile ago that people used for a short time.
Each NPC class does get reused and is even faster than a switch (which is technically multiple if's and a lot of pointless instructions to get to it's target) by invoking the script straight from a hashtable using the NPC ID not to mention being much neater & structured than stuffing tons of NPC scripts all ugly into 1 huge class. His current way looks exactly how LOTF has it and that lacks serious OOP there are boxed arrays used for almost everything.
[...]
Let's be honest he can do what he wants, but why does everyone have to follow the crowd and whats been done before? especially when they were done poorly. It's almost like you don't know of any other way, i'm just trying to give you a hand and more options. Look at Korvacs his is different, i also remember some other text based script system i think inf wrote awhile ago that people used for a short time.
Please, don't use the Hashtable class for that... Use the Dictionnary or anything else... Hashtable are very slow in comparison of the Dictionnary. You use a class that hash the Key, but you don't need that if you use the UniqId system.
For the NPC system, just make the system you like... I use external file with a system similar to INI. It's work fine and I don't use a lot of RAM or CPU. I like this system, it's easy to code, it's easy to edit and you don't need any knowledge. I can make better but I don't want. There is a lot of way for the NPC, internal or external. I think we all try to help with our system and I like to see how the other make. You can always upgrade your system with the knowlegde of others. Anyway, your system looks good and I don't think that the RAM or CPU is a real problem, but please change the Hashtable...
If your usage occurs in a frequently called method, then millions of Dialog instances can be created needlessly. Removing the needless creation of objects can sometimes significantly improve performance.
Quote:
Originally Posted by ChingChong23
and is even faster than a switch (which is technically multiple if's and a lot of pointless instructions to get to it's target) by invoking the script straight from a hashtable using the NPC ID not to mention being much neater & structured than stuffing tons of NPC scripts all ugly into 1 huge class.
Yes, why would anyone want to substitute the compiler's ability to inline and optimise switch statements with a HashTable's traversal of different buckets, and use of sometimes-expensive equality checks for the keys that reside in that table. Maybe if it increased readability! You have a point there, but arguing about the speed of these two arbitrary tactics isn't really the point here.
Quote:
Originally Posted by ChingChong23
His current way looks exactly how LOTF has it and that lacks serious OOP there are boxed arrays used for almost everything.
I was not aware that you could tell exactly how the OP's server is coded based on the snippet above.
Quote:
Originally Posted by ChingChong23
The Dialog class gets completely cleaned by the garbage collector automatically...
I think we know what the GC does.
Quote:
Originally Posted by ChingChong23
It's almost like you don't know of any other way, i'm just trying to give you a hand and more options.
I do not believe you know me, hello.
We understand your idea and why you think that it is a good one, but you've failed to understand why the OP wishes to do things his way; to keep memory usage low. I was merely adding to why it could also be faster to use the OP's current solution.
lol, if you want easy scripting, invoke ironpython (or ironruby, your choice) from your server (that is if you're coding in .NET, which I'm assuming you are).
of course the scripting will have more overhead than normal NPCs, but it's quite useful inlining them vs doing it internally.
@Viscount S: i understand that you guys wish to keep memory usage low, but you wouldn't even sacrifice a couple of mb's at max (and not even that much if done correctly) of memory for a much better structure? Memory in this situation should not even be considered. For example you saying Millions of Dialog instances can be created, while that is possible if someone decided to spam a million packets to talk to an NPC, and that's even if you have not handled it to even have a delay or check if he's already interacting with an NPC, then yes. But that's not going to happen?
@CptSky: sorry, i don't know much about .net and/or it's collections but you get the point.