📄 l1npcinstance.java
字号:
ary[1] = 1;
ary[0] = 7;
}
}
// ■■■■■■■■■■■■ アイテム関連 ■■■■■■■■■■
private void useHealPotion(int healHp, int effectId) {
broadcastPacket(new S_SkillSound(getId(), effectId));
if (this.hasSkillEffect(L1SkillId.POLLUTE_WATER)) { // ポルートウォーター中は回復量1/2倍
healHp /= 2;
}
if (this instanceof L1PetInstance) {
((L1PetInstance) this).setCurrentHp(getCurrentHp() + healHp);
} else if (this instanceof L1SummonInstance) {
((L1SummonInstance) this).setCurrentHp(getCurrentHp() + healHp);
} else {
setCurrentHpDirect(getCurrentHp() + healHp);
}
}
private void useHastePotion(int time) {
broadcastPacket(new S_SkillHaste(getId(), 1, time));
broadcastPacket(new S_SkillSound(getId(), 191));
setMoveSpeed(1);
setSkillEffect(L1SkillId.STATUS_HASTE, time * 1000);
}
// アイテムの使用判定及び使用
public static final int USEITEM_HEAL = 0;
public static final int USEITEM_HASTE = 1;
public static int[] healPotions = { POTION_OF_GREATER_HEALING,
POTION_OF_EXTRA_HEALING, POTION_OF_HEALING };
public static int[] haestPotions = { B_POTION_OF_GREATER_HASTE_SELF,
POTION_OF_GREATER_HASTE_SELF, B_POTION_OF_HASTE_SELF,
POTION_OF_HASTE_SELF };
public void useItem(int type, int chance) { // 使用する種類 使用する可能性(%)
if (hasSkillEffect(71)) {
return; // ディケイ ポーション状態かチェック
}
Random random = new Random();
if (random.nextInt(100) > chance) {
return; // 使用する可能性
}
if (type == USEITEM_HEAL) { // 回復系ポーション
// 回復量の大きい順
if (getInventory().consumeItem(POTION_OF_GREATER_HEALING, 1)) {
useHealPotion(75, 197);
} else if (getInventory().consumeItem(POTION_OF_EXTRA_HEALING, 1)) {
useHealPotion(45, 194);
} else if (getInventory().consumeItem(POTION_OF_HEALING, 1)) {
useHealPotion(15, 189);
}
} else if (type == USEITEM_HASTE) { // ヘイスト系ポーション
if (hasSkillEffect(1001)) {
return; // ヘイスト状態チェック
}
// 效果の長い順
if (getInventory().consumeItem(B_POTION_OF_GREATER_HASTE_SELF, 1)) {
useHastePotion(2100);
} else if (getInventory().consumeItem(POTION_OF_GREATER_HASTE_SELF,
1)) {
useHastePotion(1800);
} else if (getInventory().consumeItem(B_POTION_OF_HASTE_SELF, 1)) {
useHastePotion(350);
} else if (getInventory().consumeItem(POTION_OF_HASTE_SELF, 1)) {
useHastePotion(300);
}
}
}
// ■■■■■■■■■■■■■ スキル関連(npcskillsテーブル実装されたら消すかも) ■■■■■■■■■■■
// 目標の隣へテレポート
public boolean nearTeleport(int nx, int ny) {
int rdir = _random.nextInt(8);
int dir;
for (int i = 0; i < 8; i++) {
dir = rdir + i;
if (dir > 7) {
dir -= 8;
}
if (dir == 1) {
nx++;
ny--;
} else if (dir == 2) {
nx++;
} else if (dir == 3) {
nx++;
ny++;
} else if (dir == 4) {
ny++;
} else if (dir == 5) {
nx--;
ny++;
} else if (dir == 6) {
nx--;
} else if (dir == 7) {
nx--;
ny--;
} else if (dir == 0) {
ny--;
}
if (getMap().isPassable(nx, ny)) {
dir += 4;
if (dir > 7) {
dir -= 8;
}
teleport(nx, ny, dir);
setCurrentMp(getCurrentMp() - 10);
return true;
}
}
return false;
}
// 目標へテレポート
public void teleport(int nx, int ny, int dir) {
for (L1PcInstance pc : L1World.getInstance().getRecognizePlayer(this)) {
pc.sendPackets(new S_SkillSound(getId(), 169));
pc.sendPackets(new S_RemoveObject(this));
pc.removeKnownObject(this);
}
setX(nx);
setY(ny);
setHeading(dir);
}
// ----------From L1Character-------------
private String _nameId; // ● ネームID
public String getNameId() {
return _nameId;
}
public void setNameId(String s) {
_nameId = s;
}
private boolean _Agro; // ● アクティブか
public boolean isAgro() {
return _Agro;
}
public void setAgro(boolean flag) {
_Agro = flag;
}
private boolean _Agrocoi; // ● インビジアクティブか
public boolean isAgrocoi() {
return _Agrocoi;
}
public void setAgrocoi(boolean flag) {
_Agrocoi = flag;
}
private boolean _Agrososc; // ● 変身アクティブか
public boolean isAgrososc() {
return _Agrososc;
}
public void setAgrososc(boolean flag) {
_Agrososc = flag;
}
private int _homeX; // ● ホームポイントX(モンスターの戻る位置とかペットの警戒位置)
public int getHomeX() {
return _homeX;
}
public void setHomeX(int i) {
_homeX = i;
}
private int _homeY; // ● ホームポイントY(モンスターの戻る位置とかペットの警戒位置)
public int getHomeY() {
return _homeY;
}
public void setHomeY(int i) {
_homeY = i;
}
private boolean _reSpawn; // ● 再ポップするかどうか
public boolean isReSpawn() {
return _reSpawn;
}
public void setreSpawn(boolean flag) {
_reSpawn = flag;
}
private int _lightSize; // ● ライト 0.なし 1~14.大きさ
public int getLightSize() {
return _lightSize;
}
public void setLightSize(int i) {
_lightSize = i;
}
private boolean _weaponBreaked; // ● ウェポンブレイク中かどうか
public boolean isWeaponBreaked() {
return _weaponBreaked;
}
public void setWeaponBreaked(boolean flag) {
_weaponBreaked = flag;
}
private int _hiddenStatus; // ● 地中に潜ったり、空を飛んでいる状態
public int getHiddenStatus() {
return _hiddenStatus;
}
public void setHiddenStatus(int i) {
_hiddenStatus = i;
}
// 行動距離
private int _movementDistance = 0;
public int getMovementDistance() {
return _movementDistance;
}
public void setMovementDistance(int i) {
_movementDistance = i;
}
// 表示用ロウフル
private int _tempLawful = 0;
public int getTempLawful() {
return _tempLawful;
}
public void setTempLawful(int i) {
_tempLawful = i;
}
protected int calcSleepTime(int sleepTime, int type) {
switch (getMoveSpeed()) {
case 0: // 通常
break;
case 1: // ヘイスト
sleepTime -= (sleepTime * 0.25);
break;
case 2: // スロー
sleepTime *= 2;
break;
}
if (getBraveSpeed() == 1) {
sleepTime -= (sleepTime * 0.25);
}
if (hasSkillEffect(L1SkillId.WIND_SHACKLE)) {
if (type == ATTACK_SPEED || type == MAGIC_SPEED) {
sleepTime += (sleepTime * 0.25);
}
}
return sleepTime;
}
protected void setAiRunning(boolean aiRunning) {
_aiRunning = aiRunning;
}
protected boolean isAiRunning() {
return _aiRunning;
}
protected void setActived(boolean actived) {
_actived = actived;
}
protected boolean isActived() {
return _actived;
}
protected void setFirstAttack(boolean firstAttack) {
_firstAttack = firstAttack;
}
protected boolean isFirstAttack() {
return _firstAttack;
}
protected void setSleepTime(int sleep_time) {
_sleep_time = sleep_time;
}
protected int getSleepTime() {
return _sleep_time;
}
protected void setDeathProcessing(boolean deathProcessing) {
_deathProcessing = deathProcessing;
}
protected boolean isDeathProcessing() {
return _deathProcessing;
}
public int drainMana(int drain) {
if (_drainedMana >= Config.MANA_DRAIN_LIMIT_PER_NPC) {
return 0;
}
int result = Math.min(drain, getCurrentMp());
if (_drainedMana + result > Config.MANA_DRAIN_LIMIT_PER_NPC) {
result = Config.MANA_DRAIN_LIMIT_PER_NPC - _drainedMana;
}
_drainedMana += result;
return result;
}
public boolean _destroyed = false; // このインスタンスが破棄されているか
// ※破棄後に動かないよう強制的にAI等のスレッド処理中止(念のため)
// NPCが別のNPCに変わる場合の処理
protected void transform(int transformId) {
stopHpRegeneration();
stopMpRegeneration();
int transformGfxId = getNpcTemplate().getTransformGfxId();
if (transformGfxId != 0) {
broadcastPacket(new S_SkillSound(getId(), transformGfxId));
}
L1Npc npcTemplate = NpcTable.getInstance().getTemplate(transformId);
setting_template(npcTemplate);
broadcastPacket(new S_ChangeShape(getId(), getTempCharGfx()));
for (L1PcInstance pc : L1World.getInstance().getRecognizePlayer(this)) {
onPerceive(pc);
}
}
public void setRest(boolean _rest) {
this._rest = _rest;
}
public boolean isRest() {
return _rest;
}
private boolean _isResurrect;
public boolean isResurrect() {
return _isResurrect;
}
public void setResurrect(boolean flag) {
_isResurrect = flag;
}
@Override
public synchronized void resurrect(int hp) {
if (_destroyed) {
return;
}
if (_deleteTask != null) {
if (!_future.cancel(false)) { // キャンセルできない
return;
}
_deleteTask = null;
_future = null;
}
super.resurrect(hp);
// キャンセレーションをエフェクトなしでかける
// 本来は死亡時に行うべきだが、負荷が大きくなるため復活時に行う
L1SkillUse skill = new L1SkillUse();
skill.handleCommands(null, L1SkillId.CANCELLATION, getId(), getX(),
getY(), null, 0, L1SkillUse.TYPE_LOGIN, this);
}
// 死んでから消えるまでの時間計測用
private DeleteTimer _deleteTask;
private ScheduledFuture<?> _future = null;
protected synchronized void startDeleteTimer() {
if (_deleteTask != null) {
return;
}
_deleteTask = new DeleteTimer(getId());
_future = GeneralThreadPool.getInstance().schedule(_deleteTask,
Config.NPC_DELETION_TIME * 1000);
}
protected static class DeleteTimer extends TimerTask {
private int _id;
protected DeleteTimer(int oId) {
_id = oId;
if (!(L1World.getInstance().findObject(_id) instanceof L1NpcInstance)) {
throw new IllegalArgumentException("allowed only L1NpcInstance");
}
}
@Override
public void run() {
L1NpcInstance npc = (L1NpcInstance) L1World.getInstance()
.findObject(_id);
if (npc == null || !npc.isDead() || npc._destroyed) {
return; // 復活してるか、既に破棄済みだったら抜け
}
try {
npc.deleteMe();
} catch (Exception e) { // 絶対例外を投げないように
e.printStackTrace();
}
}
}
private L1MobGroupInfo _mobGroupInfo = null;
public boolean isInMobGroup() {
return getMobGroupInfo() != null;
}
public L1MobGroupInfo getMobGroupInfo() {
return _mobGroupInfo;
}
public void setMobGroupInfo(L1MobGroupInfo m) {
_mobGroupInfo = m;
}
private int _mobGroupId = 0;
public int getMobGroupId() {
return _mobGroupId;
}
public void setMobGroupId(int i) {
_mobGroupId = i;
}
public void startChat(int chatTiming) {
// 出現時のチャッ
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -