Hard-coded Npc's suck balls, so here's the starting code for Xml Npc's.
Pretty sure it was done within CoEmu v2, but can easily be converted into any source.
I haven't tested it, since I don't have a Conquer client.
Instructions:
- Includes:
Code:
using System.Xml;
Code:
using System.IO;
--- Don't forget to comment out the hard-coded npc's;
Code:
if (!File.Exists("npc/" + ID + ".xml"))
return;
XmlTextReader npcXml = new XmlTextReader("npc/" + ID + ".xml");
string type = "";
int lb = 0, current = 0;
string arg, val, sign;
arg = val = sign = null;
while (npcXml.Read())
{
switch (npcXml.NodeType)
{
case XmlNodeType.Element:
type = npcXml.Name;
switch (type)
{
case "instance":
current = Convert.ToInt32(npcXml.GetAttribute("id"));
break;
case "if":
if (current != LinkBack)
break;
arg = npcXml.GetAttribute("arg");
val = npcXml.GetAttribute("val");
sign = npcXml.GetAttribute("sign");
break;
}
break;
case XmlNodeType.Text:
npcXml.Value.Trim();
if (current != LinkBack)
continue;
if (!checkArgs(arg, val, sign, CSocket))
continue;
switch (type)
{
case "text":
string s = npcXml.Value;
s = s.Replace("@name", CSocket.Client.Name);
s = s.Replace("@level", CSocket.Client.Level.ToString());
Text(s, CSocket);
break;
case "link":
lb = Convert.ToInt32(npcXml.GetAttribute("lb"));
Link(npcXml.Value, lb, CSocket);
break;
case "input":
lb = Convert.ToInt32(npcXml.GetAttribute("lb"));
Input(npcXml.Value, lb, CSocket);
break;
}
break;
case XmlNodeType.EndElement:
if (current != LinkBack)
continue;
switch (npcXml.Name)
{
case "instance":
End(CSocket);
break;
case "if":
arg = val = sign = null;
break;
}
break;
}
}
Code:
static bool checkArgs(string arg, string val, string sign, ClientSocket CSocket)
{
if (arg == null || val == null) return true;
object lhs = new object();
object rhs = new object();
switch (arg)
{
case "reborn":
lhs = CSocket.Client.Reborn;
rhs = Convert.ToInt32(val);
break;
case "level":
lhs = CSocket.Client.Level;
rhs = Convert.ToInt32(val);
break;
case "inventorycount":
lhs = CSocket.Client.Inventory.Count;
rhs = Convert.ToInt32(val);
break;
case "inventorycontains":
if (Calculation.InventoryContains(
Convert.ToInt32(val),
Convert.ToInt32(sign), CSocket))
return true;
else return false;
}
switch (sign)
{
case "equal":
if (Convert.ToInt64(lhs.ToString()) ==
Convert.ToInt64(rhs.ToString())) return true;
else return false;
case "greatequal":
if (Convert.ToInt64(lhs.ToString()) >=
Convert.ToInt64(rhs.ToString())) return true;
else return false;
case "lessequal":
if (Convert.ToInt64(lhs.ToString()) <=
Convert.ToInt64(rhs.ToString())) return true;
else return false;
case "great":
if (Convert.ToInt64(lhs.ToString()) >
Convert.ToInt64(rhs.ToString())) return true;
else return false;
case "less":
if (Convert.ToInt64(lhs.ToString()) <
Convert.ToInt64(rhs.ToString())) return true;
else return false;
}
return false;
}
--- id is the equivalent to LinkBack
--- lb is the id to go to when the link is clicked
--- if works like a normal if statement:
------- args is what to check
------- sign (great is >, equal is ==)
------- val is what to compare
------- In the case of inventorycontains, sign is how many the inventory contains
Code:
<npc> <instance id='0'> <text>What up @name?</text> <if arg='level' sign='greatequal' val='100'> <text>At least level 100!</text> </if> <link lb='1'>Not much</link> <input lb='2'>Amount:</input> </instance> <instance id='1'> <text>Cool Cool</text> <if arg='reborn' sign='equal' val='0'> <link lb='3'>Not reborn</link> </if> <if arg='reborn' sign='great' val='0'> <link lb='3'>Reborn at least once</link> <link lb='3'>Good job</link> </if> </instance> <instance id='2'> <if arg='inventorycontains' sign='1' val='721259'> <text>You have it!</text> </if> <if arg='inventorycount' sign="lessequal" val='30'> <text>Inventory Count test!</text> </if> </instance> </npc>
Enjoy! =D
If you're interested in using this, I can add more functions over time.






