package module.command;
import java.util.ArrayList;
import module.character.CharList;
import module.character.Group;
import module.character.PlayerGroup;
import module.character.api.ICharacter;
import module.character.constants.CConfig.config;
import module.command.api.ICommand;
import module.command.api.IndexStringPair;
import module.command.character.Attack;
import module.command.character.Close;
import module.command.character.Drop;
import module.command.character.Equipment;
import module.command.character.Flee;
import module.command.character.Get;
import module.command.character.Lock;
import module.command.character.Open;
import module.command.character.Put;
import module.command.character.Remove;
import module.command.character.Unlock;
import module.command.character.Use;
import module.command.character.Wear;
import module.command.group.Inventory;
import module.command.group.Look;
import module.command.group.Mission;
import module.command.group.Move;
import module.command.group.MyTime;
import module.command.group.Quit;
import module.command.group.Talk;
import module.utility.BattleUtil;
import module.utility.EnDecoder;
import module.utility.EventUtil;
import module.utility.Parse;
public class CommandServer {
// class for all creatures in the game to interact with the world, all
// methods should be static.
// TODO: define the class
private static ArrayList<ICommand> cmdList;
private static ArrayList<ICommand> groupCmdList;
public static void initialize() {
// add all the available commands into the map
cmdList = new ArrayList<ICommand>();
groupCmdList = new ArrayList<ICommand>();
cmdList.add(new Attack());
cmdList.add(new Flee());
cmdList.add(new Get());
cmdList.add(new Drop());
cmdList.add(new Equipment());
cmdList.add(new Wear());
cmdList.add(new Remove());
cmdList.add(new Open());
cmdList.add(new Close());
cmdList.add(new Lock());
cmdList.add(new Unlock());
cmdList.add(new Put());
cmdList.add(new Use());
groupCmdList.add(new Move());
groupCmdList.add(new Look());
groupCmdList.add(new MyTime());
groupCmdList.add(new Talk());
groupCmdList.add(new Inventory());
groupCmdList.add(new Mission());
groupCmdList.add(new Quit());
}
public static void readCommand(Group g, String[] msg) {
// execute room special command
if (EventUtil.doRoomCommand(g, msg)) return;
if (msg[0].equals("help")) {
if (msg.length == 1) {
// show the top help page
informGroup(g, "Top help page.\n");
informGroup(g, showTopHelpPage());
return;
}
String output = null;
try {
ICommand target = searchCommand(msg[1], cmdList);
if (target == null)
target = searchCommand(msg[1], groupCmdList);
output = target.getHelp();
if (output == null)
output = "�|����@�ӫ��O��²���C\n";
} catch (IndexOutOfBoundsException e) {
output = "�A�Q�d�ߤ�����O?\n";
} catch (NullPointerException e) {
output = "�S���w��o�ӫ��O������.\n";
} finally {
informGroup(g, output);
}
return;
}
// check group command first
try {
ICommand targetCmd = searchCommand(msg[0], groupCmdList);
targetCmd.action(g.list.get(0).charList.get(0), msg);
return;
} catch (IndexOutOfBoundsException e) {
// do nothing
} catch (NullPointerException e) {
// do nothing
}
// then deal with character command, if no char name assigned,
// the first group character will be chosen.
ICharacter targetChar = judgePlayerCharacterMove(g, msg);
if (targetChar == null) {
targetChar = g.list.get(0).charList.get(0);
String[] temp = new String[msg.length + 1];
temp[0] = targetChar.getEngName();
for (int i = 0; i < msg.length; i++)
temp[i + 1] = msg[i];
msg = temp;
}
if (targetChar != null) {
// character-bonded action, use cmdList
if (g.getInBattle()) {
// group is in battle
int current, max;
synchronized (g.getBattleTask().getTimeMap()) {
current = g.getBattleTask().getTimeMap().get(targetChar)
.getCurrent();
max = g.getBattleTask().getTimeMap().get(targetChar)
.getMax();
}
if (current < max) {
informGroup(g, "�A��ܪ���H�٨S�dzƦn.\n");
return;
}
}
try {
ICommand targetCmd = searchCommand(msg[1], cmdList);
boolean movedInBattle = targetCmd.action(targetChar, msg);
if (movedInBattle && g.getInBattle()) {
// character has done its action, update the battle
// timer
// show character condition
g.getAtRoom().informRoom(BattleUtil.showStatusInBattle(targetChar) + "\n");
synchronized (g.getBattleTask()) {
if (g instanceof PlayerGroup) {
PlayerGroup pg = (PlayerGroup) g;
if (pg.getConfigData().get(config.REALTIMEBATTLE) == false)
pg.getBattleTask().notify();
}
if (g.getBattleTask() != null)
g.getBattleTask().resetBattleTime(targetChar);
}
}
} catch (IndexOutOfBoundsException e) {
informGroup(g,
String.format("�A�Q��%s������O?\n", targetChar.getChiName()));
} catch (NullPointerException e) {
e.printStackTrace();
informGroup(g,
String.format("�A�Q��%s������O?\n", targetChar.getChiName()));
}
return;
}
}
private static ICommand searchCommand(String msg, ArrayList<ICommand> list) {
for (ICommand cmd : list) {
for (String name : cmd.getName()) {
if (name.equals(msg))
return cmd;
}
}
return null;
}
public static void informGroup(Group g, String msg) {
if (g instanceof PlayerGroup) {
PlayerGroup g2 = (PlayerGroup) g;
EnDecoder.sendUTF8Packet(g2.getOutToClient(), msg);
} else {
// inform the NPC group about something
// do nothing first
// TODO: remove npc see mechanism, maybe add debug information?
//System.out.print(g.getChiName() + "�ݨ�: " + msg);
}
}
private static ICharacter judgePlayerCharacterMove(Group g, String[] input) {
try {
int index = Integer.parseInt(input[0]);
int count = 1;
for (CharList cList : g.list) {
for (ICharacter c : cList.charList) {
if (count == index)
return c;
count++;
}
}
return null;
} catch (Exception e) {
ICharacter target = null;
IndexStringPair pair = Parse.parseName(input[0]);
target = g.findChar(pair.name, pair.index);
return target;
}
}
private static String showTopHelpPage() {
StringBuffer buf = new StringBuffer();
buf.append("������O�G\n");
buf.append("north\tsouth\teast\twest\tup\ndown\t");
int index = 1;
while (index < groupCmdList.size()) {
buf.append(groupCmdList.get(index).getName()[0] + "\t");
index++;
if (index % 5 == 0)
buf.append("\n");
}
if (index % 5 != 0)
buf.append("\n");
buf.append("�ӤH���O�G\n");
index = 0;
while (index < cmdList.size()) {
buf.append(cmdList.get(index).getName()[0] + "\t");
index++;
if (index % 5 == 0)
buf.append("\n");
}
if (index % 5 != 0)
buf.append("\n");
return buf.toString();
}
}