02-22-2012, 08:50 PM
Доброго вечера. Ув. кодеры, помогите разобраться с мелочными проблемами, я уверен, что многие с легкостью могут сказать, как это делается и привести небольшой пример! Я был бы очень признателен!
1) как можно вывести сообщение в чат, якобы от несуществующего игрока, под каким-то ником, допустим в шаут или трейд? (на питоне или яве)?
2) Есть следующий скрипт - АИ гордона (стандартный в ИЛе), я его немножко переписал под свои нужды, хочу сделать моба, который будет бегать по моим координатам и убивать игроков (если они будут у него на пути). Вот собственно что у меня получилось:
Когда начал смотреть как это выглядит в игре, вроде бы все было нормально.. но как оказалось - где-то я ошибся с таймерами, потому что когда он бьет игрока - начинает дергаться и убегать, а не убивает до конца и только потом бежит дальше.. Хотелось бы сделать так, что бы перерыв между "бегами" в следующую точку был равен нулю, т.е. передвижение было постоянное, а вот только тогда, если он кого-нибудь увидит в своем аггро радиусе - сразу килл, не увидит - так и пусть бежит себе дальше?
3) Существуют проверки на зоны:
, вопрос - как можно сделать проверку (для запрета атаки скиллами и простыми ударами), на зону, для определенного Instance - в данном случае L2WalkerRoute? Т.е. если этот нпц в городе - то нельзя никаким образом аттаковать (как простых игроков), если за городом - можно.
4) и последнее - вопрос касается тех же L2WalkerRoute, копался в их коде, пытался сделать так, что бы их можно было "убивать вообще". потому как они были до этого бессмертны (и проблема была явно в ядре), собственно проблема и осталась - их невозможно убить, хотя хп вроде бы уходит и бить их можно. Вот код, который получилось слепить:
СПАСИБО большое всем, за любые ответы.
1) как можно вывести сообщение в чат, якобы от несуществующего игрока, под каким-то ником, допустим в шаут или трейд? (на питоне или яве)?
2) Есть следующий скрипт - АИ гордона (стандартный в ИЛе), я его немножко переписал под свои нужды, хочу сделать моба, который будет бегать по моим координатам и убивать игроков (если они будут у него на пути). Вот собственно что у меня получилось:
Код:
package com.l2jfrozen.gameserver.ai.special;
import java.util.Collection;
import com.l2jfrozen.gameserver.ai.CtrlIntention;
import com.l2jfrozen.gameserver.datatables.sql.SpawnTable;
import com.l2jfrozen.gameserver.model.L2Attackable;
import com.l2jfrozen.gameserver.model.actor.instance.L2NpcInstance;
import com.l2jfrozen.gameserver.model.actor.instance.L2PcInstance;
import com.l2jfrozen.gameserver.model.actor.instance.L2MonsterInstance;
import com.l2jfrozen.gameserver.model.actor.position.L2CharPosition;
import com.l2jfrozen.gameserver.model.actor.instance.L2ItemInstance;
import com.l2jfrozen.gameserver.model.quest.Quest;
import com.l2jfrozen.gameserver.model.quest.QuestState;
import com.l2jfrozen.gameserver.model.spawn.L2Spawn;
import com.l2jfrozen.util.random.Rnd;
public class di_knight extends Quest implements Runnable
{
private static final int KNIGHT = 70568; //KnighT
private static int _npcMoveX = 0;
private static int _npcMoveY = 0;
private static int _isWalkTo = 0;
private static int _npcBlock = 0;
private static int X = 0;
private static int Y = 0;
private static int Z = 0;
private static final int[][] WALKS =
{
{
19816, -15679, -3091
},
{
22452, -14854, -3061
},
{
19889, -15918, -3084
},
{
19914, -16255, -3086
},
{
18967, -15830, -3093
}
};
private static boolean _isAttacked = false;
private static boolean _isSpawned = false;
public di_knight(int id, String name, String descr)
{
super(id, name, descr);
addEventId(KNIGHT, Quest.QuestEventType.ON_KILL);
addEventId(KNIGHT, Quest.QuestEventType.ON_ATTACK);
addEventId(KNIGHT, Quest.QuestEventType.ON_SPAWN);
// wait 2 minutes after Start AI
startQuestTimer("check_ai", 12000, null, null,true);
_isSpawned = false;
_isAttacked = false;
_isWalkTo = 1;
_npcMoveX = 0;
_npcMoveY = 0;
_npcBlock = 0;
}
@Override
public String onAdvEvent(String event, L2NpcInstance npc, L2PcInstance player)
{
X = WALKS[_isWalkTo - 1][0];
Y = WALKS[_isWalkTo - 1][1];
Z = WALKS[_isWalkTo - 1][2];
if(event == "time_isAttacked")
{
_isAttacked = false;
if(npc.getNpcId() == KNIGHT)
{
npc.setRunning();
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new L2CharPosition(X, Y, Z, 0));
}
}
else if(event == "check_ai")
{
cancelQuestTimer("check_ai", null, null);
if(_isSpawned == false)
{
L2NpcInstance KNIGHT_ai = findTemplate(KNIGHT);
if(KNIGHT_ai != null)
{
_isSpawned = true;
startQuestTimer("Start", 12000, KNIGHT_ai, null,true);
return super.onAdvEvent(event, npc, player);
}
}
}
else if(event == "Start")
{
//startQuestTimer("Start", 1000, npc, null);
if(npc != null && _isSpawned == true)
{
// check if player in radius
if(npc.getNpcId() == KNIGHT)
{
Collection<L2PcInstance> chars = npc.getKnownList().getKnownPlayers().values();
if(chars != null && chars.size() > 0)
{
for(L2PcInstance pc : chars)
{
if(pc.isInsideRadius(npc, 5000, false, false))
{
npc.setRunning();
((L2Attackable) npc).addDamageHate(pc, 0, 9999);
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, pc);
_isAttacked = true;
cancelQuestTimer("time_isAttacked", null, null);
startQuestTimer("time_isAttacked", 12000, npc, null);
return super.onAdvEvent(event, npc, player);
}
}
}
}
// end check
if(_isAttacked == true)
return super.onAdvEvent(event, npc, player);
if(npc.getNpcId() == KNIGHT && npc.getX() - 50 <= X && npc.getX() + 50 >= X && npc.getY() - 50 <= Y && npc.getY() + 50 >= Y)
{
_isWalkTo++;
if(_isWalkTo > 6) //change WALKS number
{
_isWalkTo = 1;
}
X = WALKS[_isWalkTo - 1][0];
Y = WALKS[_isWalkTo - 1][1];
Z = WALKS[_isWalkTo - 1][2];
npc.setRunning();
}
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onSpawn(L2NpcInstance npc)
{
if(npc.getNpcId() == KNIGHT && _npcBlock == 0)
{
_isSpawned = true;
_isWalkTo = 1;
startQuestTimer("Start", 12000, npc, null);
}
return super.onSpawn(npc);
}
@Override
public String onAttack(L2NpcInstance npc, L2PcInstance player, int damage, boolean isPet)
{
if(npc.getNpcId() == KNIGHT)
{
_isAttacked = true;
cancelQuestTimer("time_isAttacked", null, null);
startQuestTimer("time_isAttacked", 12000, npc, null);
if(player != null)
{
npc.setRunning();
((L2Attackable) npc).addDamageHate(player, 0, 100);
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, player);
}
}
return super.onAttack(npc, player, damage, isPet);
}
@Override
public String onKill(L2NpcInstance npc, L2PcInstance killer, boolean isPet)
{
if(npc.getNpcId() == KNIGHT)
{
cancelQuestTimer("Start", null, null);
cancelQuestTimer("time_isAttacked", null, null);
_isSpawned = false;
}
return super.onKill(npc, killer, isPet);
}
public L2NpcInstance findTemplate(int npcId)
{
L2NpcInstance npc = null;
for(L2Spawn spawn : SpawnTable.getInstance().getSpawnTable().values())
{
if(spawn != null && spawn.getNpcid() == npcId)
{
npc = spawn.getLastSpawn();
break;
}
}
return npc;
}
@Override
public void run()
{}
}
Когда начал смотреть как это выглядит в игре, вроде бы все было нормально.. но как оказалось - где-то я ошибся с таймерами, потому что когда он бьет игрока - начинает дергаться и убегать, а не убивает до конца и только потом бежит дальше.. Хотелось бы сделать так, что бы перерыв между "бегами" в следующую точку был равен нулю, т.е. передвижение было постоянное, а вот только тогда, если он кого-нибудь увидит в своем аггро радиусе - сразу килл, не увидит - так и пусть бежит себе дальше?
3) Существуют проверки на зоны:
Код:
ZoneManager.getInstance().getZoneById(ZoneType.TYP E, ZONE_ID, false);
, вопрос - как можно сделать проверку (для запрета атаки скиллами и простыми ударами), на зону, для определенного Instance - в данном случае L2WalkerRoute? Т.е. если этот нпц в городе - то нельзя никаким образом аттаковать (как простых игроков), если за городом - можно.
4) и последнее - вопрос касается тех же L2WalkerRoute, копался в их коде, пытался сделать так, что бы их можно было "убивать вообще". потому как они были до этого бессмертны (и проблема была явно в ядре), собственно проблема и осталась - их невозможно убить, хотя хп вроде бы уходит и бить их можно. Вот код, который получилось слепить:
Код:
@Override
public void reduceCurrentHp(double i, L2Character attacker, boolean awake)
{
super.reduceCurrentHp(i, attacker, awake);
}
/**
* NPCs are immortal
*
* @param killer ignore it
* @return false
**/
@Override
public boolean doDie(L2Character killer)
{
if(!super.doDie(killer))
return false;
return true;
}
СПАСИБО большое всем, за любые ответы.