📄 l1pcinstance.java
字号:
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* http://www.gnu.org/copyleft/gpl.html
*/
package l1j.server.server.model.Instance;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.concurrent.ScheduledFuture;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.sql.Timestamp;
import l1j.server.Config;
import l1j.server.server.ActionCodes;
import l1j.server.server.ClientThread;
import l1j.server.server.GMCommands;
import l1j.server.server.GeneralThreadPool;
import l1j.server.server.PacketOutput;
import l1j.server.server.WarTimeController;
import l1j.server.server.command.executor.L1HpBar;
import l1j.server.server.datatables.CharacterTable;
import l1j.server.server.datatables.ExpTable;
import l1j.server.server.datatables.ItemTable;
import l1j.server.server.model.HpRegeneration;
import l1j.server.server.model.AcceleratorChecker;
import l1j.server.server.model.L1Attack;
import l1j.server.server.model.L1CastleLocation;
import l1j.server.server.model.L1Character;
import l1j.server.server.model.L1ChatParty;
import l1j.server.server.model.L1Clan;
import l1j.server.server.model.L1DwarfForElfInventory;
import l1j.server.server.model.L1DwarfInventory;
import l1j.server.server.model.L1EquipmentSlot;
import l1j.server.server.model.L1ExcludingList;
import l1j.server.server.model.L1Inventory;
import l1j.server.server.model.L1Karma;
import l1j.server.server.model.L1Magic;
import l1j.server.server.model.L1Object;
import l1j.server.server.model.L1Party;
import l1j.server.server.model.L1PcInventory;
import l1j.server.server.model.L1PinkName;
import l1j.server.server.model.L1Quest;
import l1j.server.server.model.L1Teleport;
import l1j.server.server.model.L1TownLocation;
import l1j.server.server.model.L1War;
import l1j.server.server.model.L1World;
import l1j.server.server.model.MpReductionByAwake;
import l1j.server.server.model.MpRegeneration;
import l1j.server.server.model.MpRegenerationByDoll;
import l1j.server.server.model.classes.L1ClassFeature;
import l1j.server.server.model.gametime.L1GameTimeCarrier;
import l1j.server.server.model.monitor.L1PcAutoUpdate;
import l1j.server.server.model.monitor.L1PcExpMonitor;
import l1j.server.server.model.monitor.L1PcGhostMonitor;
import l1j.server.server.model.monitor.L1PcHellMonitor;
import l1j.server.server.model.monitor.L1PcInvisDelay;
import l1j.server.server.model.skill.L1SkillId;
import l1j.server.server.model.skill.L1SkillUse;
import l1j.server.server.serverpackets.S_BlueMessage;
import l1j.server.server.serverpackets.S_Exp;
import l1j.server.server.serverpackets.S_bonusstats;
import l1j.server.server.serverpackets.S_CastleMaster;
import l1j.server.server.serverpackets.S_ChangeShape;
import l1j.server.server.serverpackets.S_Disconnect;
import l1j.server.server.serverpackets.S_RemoveObject;
import l1j.server.server.serverpackets.S_DoActionGFX;
import l1j.server.server.serverpackets.S_DoActionShop;
import l1j.server.server.serverpackets.S_Emblem;
import l1j.server.server.serverpackets.S_HPMeter;
import l1j.server.server.serverpackets.S_HPUpdate;
import l1j.server.server.serverpackets.S_Invis;
import l1j.server.server.serverpackets.S_Lawful;
import l1j.server.server.serverpackets.S_Liquor;
import l1j.server.server.serverpackets.S_MPUpdate;
import l1j.server.server.serverpackets.S_OtherCharPacks;
import l1j.server.server.serverpackets.S_OwnCharStatus;
import l1j.server.server.serverpackets.S_PacketBox;
import l1j.server.server.serverpackets.S_Poison;
import l1j.server.server.serverpackets.S_ServerMessage;
import l1j.server.server.serverpackets.S_SkillIconGFX;
import l1j.server.server.serverpackets.S_SystemMessage;
import l1j.server.server.serverpackets.ServerBasePacket;
import l1j.server.server.templates.L1BookMark;
import l1j.server.server.templates.L1Item;
import l1j.server.server.templates.L1PrivateShopBuyList;
import l1j.server.server.templates.L1PrivateShopSellList;
import l1j.server.server.utils.CalcStat;
import l1j.server.server.utils.IntRange;
// Referenced classes of package l1j.server.server.model:
// L1Character, L1DropTable, L1Object, L1ItemInstance,
// L1World
//
public class L1PcInstance extends L1Character {
private static final long serialVersionUID = 1L;
public static final int CLASSID_KNIGHT_MALE = 61;
public static final int CLASSID_KNIGHT_FEMALE = 48;
public static final int CLASSID_ELF_MALE = 138;
public static final int CLASSID_ELF_FEMALE = 37;
public static final int CLASSID_WIZARD_MALE = 734;
public static final int CLASSID_WIZARD_FEMALE = 1186;
public static final int CLASSID_DARK_ELF_MALE = 2786;
public static final int CLASSID_DARK_ELF_FEMALE = 2796;
public static final int CLASSID_PRINCE = 0;
public static final int CLASSID_PRINCESS = 1;
public static final int CLASSID_DRAGON_KNIGHT_MALE = 6658;
public static final int CLASSID_DRAGON_KNIGHT_FEMALE = 6661;
public static final int CLASSID_ILLUSIONIST_MALE = 6671;
public static final int CLASSID_ILLUSIONIST_FEMALE = 6650;
private short _hpr = 0;
private short _trueHpr = 0;
public short getHpr() {
return _hpr;
}
public void addHpr(int i) {
_trueHpr += i;
_hpr = (short) Math.max(0, _trueHpr);
}
private short _mpr = 0;
private short _trueMpr = 0;
public short getMpr() {
return _mpr;
}
public void addMpr(int i) {
_trueMpr += i;
_mpr = (short) Math.max(0, _trueMpr);
}
public short _originalHpr = 0; // ● オリジナルCON HPR
public short getOriginalHpr() {
return _originalHpr;
}
public short _originalMpr = 0; // ● オリジナルWIS MPR
public short getOriginalMpr() {
return _originalMpr;
}
public void startHpRegeneration() {
final int INTERVAL = 1000;
if (!_hpRegenActive) {
_hpRegen = new HpRegeneration(this);
_regenTimer.scheduleAtFixedRate(_hpRegen, INTERVAL, INTERVAL);
_hpRegenActive = true;
}
}
public void stopHpRegeneration() {
if (_hpRegenActive) {
_hpRegen.cancel();
_hpRegen = null;
_hpRegenActive = false;
}
}
public void startMpRegeneration() {
final int INTERVAL = 1000;
if (!_mpRegenActive) {
_mpRegen = new MpRegeneration(this);
_regenTimer.scheduleAtFixedRate(_mpRegen, INTERVAL, INTERVAL);
_mpRegenActive = true;
}
}
public void startMpRegenerationByDoll() {
final int INTERVAL_BY_DOLL = 60000;
boolean isExistMprDoll = false;
Object[] dollList = getDollList().values().toArray();
for (Object dollObject : dollList) {
L1DollInstance doll = (L1DollInstance) dollObject;
if (doll.isMpRegeneration()) {
isExistMprDoll = true;
}
}
if (!_mpRegenActiveByDoll && isExistMprDoll) {
_mpRegenByDoll = new MpRegenerationByDoll(this);
_regenTimer.scheduleAtFixedRate(_mpRegenByDoll, INTERVAL_BY_DOLL,
INTERVAL_BY_DOLL);
_mpRegenActiveByDoll = true;
}
}
public void startMpReductionByAwake() {
final int INTERVAL_BY_AWAKE = 4000;
if (!_mpReductionActiveByAwake) {
_mpReductionByAwake = new MpReductionByAwake(this);
_regenTimer.scheduleAtFixedRate(_mpReductionByAwake,
INTERVAL_BY_AWAKE, INTERVAL_BY_AWAKE);
_mpReductionActiveByAwake = true;
}
}
public void stopMpRegeneration() {
if (_mpRegenActive) {
_mpRegen.cancel();
_mpRegen = null;
_mpRegenActive = false;
}
}
public void stopMpRegenerationByDoll() {
if (_mpRegenActiveByDoll) {
_mpRegenByDoll.cancel();
_mpRegenByDoll = null;
_mpRegenActiveByDoll = false;
}
}
public void stopMpReductionByAwake() {
if (_mpReductionActiveByAwake) {
_mpReductionByAwake.cancel();
_mpReductionByAwake = null;
_mpReductionActiveByAwake = false;
}
}
public void startObjectAutoUpdate() {
removeAllKnownObjects();
_autoUpdateFuture = GeneralThreadPool.getInstance()
.pcScheduleAtFixedRate(new L1PcAutoUpdate(getId()), 0L,
INTERVAL_AUTO_UPDATE);
}
/**
* 各種モニタータスクを停止する。
*/
public void stopEtcMonitor() {
if (_autoUpdateFuture != null) {
_autoUpdateFuture.cancel(true);
_autoUpdateFuture = null;
}
if (_expMonitorFuture != null) {
_expMonitorFuture.cancel(true);
_expMonitorFuture = null;
}
if (_ghostFuture != null) {
_ghostFuture.cancel(true);
_ghostFuture = null;
}
if (_hellFuture != null) {
_hellFuture.cancel(true);
_hellFuture = null;
}
}
private static final long INTERVAL_AUTO_UPDATE = 300;
private ScheduledFuture<?> _autoUpdateFuture;
private static final long INTERVAL_EXP_MONITOR = 500;
private ScheduledFuture<?> _expMonitorFuture;
public void onChangeExp() {
int level = ExpTable.getLevelByExp(getExp());
int char_level = getLevel();
int gap = level - char_level;
if (gap == 0) {
// sendPackets(new S_OwnCharStatus(this));
sendPackets(new S_Exp(this));
return;
}
// レベルが変化した場合
if (gap > 0) {
levelUp(gap);
} else if (gap < 0) {
levelDown(gap);
}
}
@Override
public void onPerceive(L1PcInstance perceivedFrom) {
if (isGmInvis() || isGhost() || isInvisble()) {
return;
}
perceivedFrom.addKnownObject(this);
perceivedFrom.sendPackets(new S_OtherCharPacks(this)); // 自分の情報を送る
if (isInParty() && getParty().isMember(perceivedFrom)) { // PTメンバーならHPメーターも送る
perceivedFrom.sendPackets(new S_HPMeter(this));
}
if (isPrivateShop()) {
perceivedFrom.sendPackets(new S_DoActionShop(getId(),
ActionCodes.ACTION_Shop, getShopChat()));
}
if (isCrown()) { // 君主
L1Clan clan = L1World.getInstance().getClan(getClanname());
if (clan != null) {
if (getId() == clan.getLeaderId() // 血盟主で城主クラン
&& clan.getCastleId() != 0) {
perceivedFrom.sendPackets(new S_CastleMaster(clan
.getCastleId(), getId()));
}
}
}
}
// 範囲外になった認識済みオブジェクトを除去
private void removeOutOfRangeObjects() {
for (L1Object known : getKnownObjects()) {
if (known == null) {
continue;
}
if (Config.PC_RECOGNIZE_RANGE == -1) {
if (!getLocation().isInScreen(known.getLocation())) { // 画面外
removeKnownObject(known);
sendPackets(new S_RemoveObject(known));
}
} else {
if (getLocation().getTileLineDistance(known.getLocation()) > Config.PC_RECOGNIZE_RANGE) {
removeKnownObject(known);
sendPackets(new S_RemoveObject(known));
}
}
}
}
// オブジェクト認識処理
public void updateObject() {
removeOutOfRangeObjects();
// 認識範囲内のオブジェクトリストを作成
for (L1Object visible : L1World.getInstance().getVisibleObjects(this,
Config.PC_RECOGNIZE_RANGE)) {
if (!knownsObject(visible)) {
visible.onPerceive(this);
} else {
if (visible instanceof L1NpcInstance) {
L1NpcInstance npc = (L1NpcInstance) visible;
if (getLocation().isInScreen(npc.getLocation())
&& npc.getHiddenStatus() != 0) {
npc.approachPlayer(this);
}
}
}
//所有人都看的到怪物血條
if (hasSkillEffect(L1SkillId.GMSTATUS_HPBAR)
&& L1HpBar.isHpBarTarget(visible)) {
sendPackets(new S_HPMeter((L1Character) visible));
} else if(Config.SHOW_HP_BAR && L1HpBar.isHpBarTarget(visible)
&& visible instanceof L1MonsterInstance ){
sendPackets(new S_HPMeter((L1Character) visible));
}
//~所有人都看的到怪物血條
}
}
private void sendVisualEffect() {
int poisonId = 0;
if (getPoison() != null) { // 毒状態
poisonId = getPoison().getEffectId();
}
if (getParalysis() != null) { // 麻痺状態
// 麻痺エフェクトを優先して送りたい為、poisonIdを上書き。
poisonId = getParalysis().getEffectId();
}
if (poisonId != 0) { // このifはいらないかもしれない
sendPackets(new S_Poison(getId(), poisonId));
broadcastPacket(new S_Poison(getId(), poisonId));
}
}
public void sendVisualEffectAtLogin() {
for (L1Clan clan : L1World.getInstance().getAllClans()) {
sendPackets(new S_Emblem(clan.getClanId()));
}
if (getClanid() != 0) { // クラン所属
L1Clan clan = L1World.getInstance().getClan(getClanname());
if (clan != null) {
if (isCrown() && getId() == clan.getLeaderId() && // プリンスまたはプリンセス、かつ、血盟主で自クランが城主
clan.getCastleId() != 0) {
sendPackets(new S_CastleMaster(clan.getCastleId(), getId()));
}
}
}
sendVisualEffect();
}
public void sendVisualEffectAtTeleport() {
if (isDrink()) { // liquorで酔っている
sendPackets(new S_Liquor(getId()));
}
sendVisualEffect();
}
public L1PcInstance() {
_accessLevel = 0;
_currentWeapon = 0;
_inventory = new L1PcInventory(this);
_dwarf = new L1DwarfInventory(this);
_dwarfForElf = new L1DwarfForElfInventory(this);
_tradewindow = new L1Inventory();
_bookmarks = new ArrayList<L1BookMark>();
_quest = new L1Quest(this);
_equipSlot = new L1EquipmentSlot(this); // コンストラクタでthisポインタを渡すのは安全だろうか
}
@Override
public void setCurrentHp(int i) {
if (getCurrentHp() == i) {
return;
}
int currentHp = i;
if (currentHp >= getMaxHp()) {
currentHp = getMaxHp();
}
setCurrentHpDirect(currentHp);
sendPackets(new S_HPUpdate(currentHp, getMaxHp()));
if (isInParty()) { // パーティー中
getParty().updateMiniHP(this);
}
}
@Override
public void setCurrentMp(int i) {
if (getCurrentMp() == i) {
return;
}
int currentMp = i;
if (currentMp >= getMaxMp() || isGm()) {
currentMp = getMaxMp();
}
setCurrentMpDirect(currentMp);
sendPackets(new S_MPUpdate(currentMp, getMaxMp()));
}
@Override
public L1PcInventory getInventory() {
return _inventory;
}
public L1DwarfInventory getDwarfInventory() {
return _dwarf;
}
public L1DwarfForElfInventory getDwarfForElfInventory() {
return _dwarfForElf;
}
public L1Inventory getTradeWindowInventory() {
return _tradewindow;
}
public boolean isGmInvis() {
return _gmInvis;
}
public void setGmInvis(boolean flag) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -