class file1: package net.sf.l2j.gameserver; import java.io.FileReader; import java.util.ArrayList; import java.util.logging.Logger; import net.sf.l2j.Config; import net.sf.l2j.fscript.L2JAIExtension; public class AIScript { private static Logger _log = Logger.getLogger(AIScript.class.getName()); private static L2JAIExtension fs; private static AIScript _instance; private static final int AIVersion=100; public boolean _debug; public AIScript() { fs = new L2JAIExtension(); reload(); } public static AIScript getInstance() { if(_instance == null) _instance = new AIScript(); return _instance; } public void reload() { try { _log.info("AIScript: loading script..."); fs.reset(); fs.load( new FileReader(Config.DATAPACK_ROOT+"/data/ai.obj")); _log.info("AIScript: executing..."); fs.run(); _debug = false; if((Integer)(fs.getScriptVar("L2JAIVersion")) != AIVersion) { _log.warning("Invalid ai.obj version!"); } if((Integer)(fs.getScriptVar("L2JAIDebug")) == 1) { _log.info("AIScript: debugging enabled"); _debug = true; } } catch(Exception e) { _log.warning("Error loading ai.obj: "+e); e.printStackTrace(); } } /** * Handle interrupt issued by AbstractAI onEvent handler * @param handler - handler name * @param params - params array * first param are always reference to 'self' - caller ObjectID * @return - ai handler output value, CAN BE NULL */ public Object handleInterrupt(String handler,ArrayList params) { Object result = null; if(params == null) { params = new ArrayList(); } try { result = fs.callScriptFunction(handler,params); } catch(Exception e) { _log.warning("AIScript: ERROR WHILE HANDLING INTERRUPT! "+e); } return result; } } class file2: package net.sf.l2j.fscript; import java.util.ArrayList; import net.sf.l2j.gameserver.AIScript; import net.sf.l2j.gameserver.model.L2Character; import net.sf.l2j.gameserver.model.L2NpcInstance; import net.sf.l2j.gameserver.model.L2PcInstance; import net.sf.l2j.gameserver.model.L2World; import net.sf.l2j.gameserver.serverpackets.CreatureSay; public class L2JAIExtension extends FScript { private Object files[]; /**Constructor*/ public L2JAIExtension() { super(); files=new Object[25]; } public Object callFunction(String name,ArrayList param) throws FSException { if (name.equals("dbgprint")) { if(AIScript.getInstance()._debug) { String s=""; for(int n=0;n args = new ArrayList(); + args.add(_actor.getObjectId()); + args.add(attacker.getObjectId()); + AIScript.getInstance().handleInterrupt("onEventAttacked",args); + // Calculate the attack timeout _attack_timeout = MAX_ATTACK_TIMEOUT + GameTimeController.getGameTicks(); admin handler: package net.sf.l2j.gameserver.handler.admincommandhandlers; import net.sf.l2j.gameserver.AIScript; import net.sf.l2j.gameserver.handler.IAdminCommandHandler; import net.sf.l2j.gameserver.model.L2PcInstance; public class AdminAI implements IAdminCommandHandler { private static String[] _adminCommands = {"admin_ai_reload"}; public boolean useAdminCommand(String command, L2PcInstance activeChar) { if (command.equals("admin_ai_reload")) { AIScript.getInstance().reload(); } return true; } public String[] getAdminCommandList() { return _adminCommands; } } ai.obj: int L2JAIVersion=100 int L2JAIDebug=1 func onIdle(int objectId) dbgprint("idle") endfunc ########################################## # real events goes here ########################################## func onEventThink(int self) dbgprint("handling event: Think ") endfunc func onEventAttacked(int self, int attacker) dbgprint("handling event: Attacked, by oid: "+attacker) string playerName=getPlayerName(attacker) #dbgprint(playerName) double currentHp=GetHP(self) Say(self,"OMFG! I'm attacked by "+playerName+"! My hp are: "+currentHp) string class=GetNpcClass(self) dbgprint("class: "+class) endfunc func onEventAggression(int self, int target, int value) dbgprint("handling event: Aggression") endfunc func onEventReady(int self) dbgprint("handling event: ready") endfunc func onEventArrived(int self) dbgprint("handling event: Arrived") endfunc func onEventDead(int self) dbgprint("handling event: Dead") endfunc