📄 l1pcinstance.java
字号:
}
public void receiveManaDamage(L1Character attacker, int mpDamage) { // 攻撃でMPを減らすときはここを使用
if (mpDamage > 0 && !isDead()) {
delInvis();
if (attacker instanceof L1PcInstance) {
L1PinkName.onAction(this, attacker);
}
if (attacker instanceof L1PcInstance
&& ((L1PcInstance) attacker).isPinkName()) {
// ガードが画面内にいれば、攻撃者をガードのターゲットに設定する
for (L1Object object : L1World.getInstance().getVisibleObjects(
attacker)) {
if (object instanceof L1GuardInstance) {
L1GuardInstance guard = (L1GuardInstance) object;
guard.setTarget(((L1PcInstance) attacker));
}
}
}
int newMp = getCurrentMp() - mpDamage;
if (newMp > getMaxMp()) {
newMp = getMaxMp();
}
if (newMp <= 0) {
newMp = 0;
}
setCurrentMp(newMp);
}
}
public void receiveDamage(L1Character attacker, int damage) { // 攻撃でHPを減らすときはここを使用
if (getCurrentHp() > 0 && !isDead()) {
if (attacker != this && !knownsObject(attacker)
&& attacker.getMapId() == this.getMapId()) {
attacker.onPerceive(this);
}
if (damage > 0) {
delInvis();
if (attacker instanceof L1PcInstance) {
L1PinkName.onAction(this, attacker);
}
if (attacker instanceof L1PcInstance
&& ((L1PcInstance) attacker).isPinkName()) {
// ガードが画面内にいれば、攻撃者をガードのターゲットに設定する
for (L1Object object : L1World.getInstance()
.getVisibleObjects(attacker)) {
if (object instanceof L1GuardInstance) {
L1GuardInstance guard = (L1GuardInstance) object;
guard.setTarget(((L1PcInstance) attacker));
}
}
}
removeSkillEffect(L1SkillId.FOG_OF_SLEEPING);
}
if (getInventory().checkEquipped(145) // バーサーカーアックス
|| getInventory().checkEquipped(149)) { // ミノタウルスアックス
damage *= 1.5; // 被ダメ1.5倍
}
if (hasSkillEffect(L1SkillId.ILLUSION_AVATAR)) {
damage *= 1.5; // 被ダメ1.5倍
}
int newHp = getCurrentHp() - damage;
if (newHp > getMaxHp()) {
newHp = getMaxHp();
}
if (newHp <= 0) {
if (isGm()) {
setCurrentHp(getMaxHp());
} else {
death(attacker);
}
}
if (newHp > 0) {
setCurrentHp(newHp);
}
} else if (!isDead()) { // 念のため
System.out
.println("警告︰PC的hp減少處理出現錯誤。※將視為hp=0作處理");
death(attacker);
}
}
public void death(L1Character lastAttacker) {
synchronized (this) {
if (isDead()) {
return;
}
setDead(true);
setStatus(ActionCodes.ACTION_Die);
}
GeneralThreadPool.getInstance().execute(new Death(lastAttacker));
}
private class Death implements Runnable {
L1Character _lastAttacker;
Death(L1Character cha) {
_lastAttacker = cha;
}
public void run() {
L1Character lastAttacker = _lastAttacker;
_lastAttacker = null;
setCurrentHp(0);
setGresValid(false); // EXPロストするまでG-RES無效
while (isTeleport()) { // テレポート中なら終わるまで待つ
try {
Thread.sleep(300);
} catch (Exception e) {
}
}
stopHpRegeneration();
stopMpRegeneration();
int targetobjid = getId();
getMap().setPassable(getLocation(), true);
// エンチャントを解除する
// 変身状態も解除されるため、キャンセレーションをかけてから変身状態に戻す
int tempchargfx = 0;
if (hasSkillEffect(L1SkillId.SHAPE_CHANGE)) {
tempchargfx = getTempCharGfx();
setTempCharGfxAtDead(tempchargfx);
} else {
setTempCharGfxAtDead(getClassId());
}
// キャンセレーションをエフェクトなしでかける
L1SkillUse l1skilluse = new L1SkillUse();
l1skilluse.handleCommands(L1PcInstance.this,
L1SkillId.CANCELLATION, getId(), getX(), getY(), null, 0,
L1SkillUse.TYPE_LOGIN);
// シャドウ系変身中に死亡するとクライアントが落ちるため暫定対応
if (tempchargfx == 5727 || tempchargfx == 5730
|| tempchargfx == 5733 || tempchargfx == 5736) {
tempchargfx = 0;
}
if (tempchargfx != 0) {
sendPackets(new S_ChangeShape(getId(), tempchargfx));
broadcastPacket(new S_ChangeShape(getId(), tempchargfx));
} else {
// シャドウ系変身中に攻撃しながら死亡するとクライアントが落ちるためディレイを入れる
try {
Thread.sleep(1000);
} catch (Exception e) {
}
}
sendPackets(new S_DoActionGFX(targetobjid, ActionCodes.ACTION_Die));
broadcastPacket(new S_DoActionGFX(targetobjid,
ActionCodes.ACTION_Die));
if (lastAttacker != L1PcInstance.this) {
// セーフティーゾーン、コンバットゾーンで最後に殺したキャラが
// プレイヤーorペットだったら、ペナルティなし
if (getZoneType() != 0) {
L1PcInstance player = null;
if (lastAttacker instanceof L1PcInstance) {
player = (L1PcInstance) lastAttacker;
} else if (lastAttacker instanceof L1PetInstance) {
player = (L1PcInstance) ((L1PetInstance) lastAttacker)
.getMaster();
} else if (lastAttacker instanceof L1SummonInstance) {
player = (L1PcInstance) ((L1SummonInstance) lastAttacker)
.getMaster();
}
if (player != null) {
// 戦争中に戦争エリアに居る場合は例外
if (!isInWarAreaAndWarTime(L1PcInstance.this, player)) {
return;
}
}
}
boolean sim_ret = simWarResult(lastAttacker); // 模擬戦
if (sim_ret == true) { // 模擬戦中ならペナルティなし
return;
}
}
if (!getMap().isEnabledDeathPenalty()) {
return;
}
// 決闘中ならペナルティなし
L1PcInstance fightPc = null;
if (lastAttacker instanceof L1PcInstance) {
fightPc = (L1PcInstance) lastAttacker;
}
if (fightPc != null) {
if (getFightId() == fightPc.getId()
&& fightPc.getFightId() == getId()) { // 決闘中
setFightId(0);
sendPackets(new S_PacketBox(S_PacketBox.MSG_DUEL, 0, 0));
fightPc.setFightId(0);
fightPc.sendPackets(new S_PacketBox(S_PacketBox.MSG_DUEL,
0, 0));
return;
}
}
deathPenalty(); // EXPロスト
setGresValid(true); // EXPロストしたらG-RES有效
if (getExpRes() == 0) {
setExpRes(1);
}
// ガードに殺された場合のみ、PKカウントを減らしガードに攻撃されなくなる
if (lastAttacker instanceof L1GuardInstance) {
if (get_PKcount() > 0) {
set_PKcount(get_PKcount() - 1);
}
setLastPk(null);
}
// 一定の確率でアイテムをDROP
// アライメント32000以上で0%、以降-1000毎に0.4%
// アライメントが0未満の場合は-1000毎に0.8%
// アライメント-32000以下で最高51.2%のDROP率
int lostRate = (int) (((getLawful() + 32768D) / 1000D - 65D) * 4D);
if (lostRate < 0) {
lostRate *= -1;
if (getLawful() < 0) {
lostRate *= 2;
}
Random random = new Random();
int rnd = random.nextInt(1000) + 1;
if (rnd <= lostRate) {
int count = 1;
if (getLawful() <= -30000) {
count = random.nextInt(4) + 1;
} else if (getLawful() <= -20000) {
count = random.nextInt(3) + 1;
} else if (getLawful() <= -10000) {
count = random.nextInt(2) + 1;
} else if (getLawful() < 0) {
count = random.nextInt(1) + 1;
}
caoPenaltyResult(count);
}
}
boolean castle_ret = castleWarResult(); // 攻城戦
if (castle_ret == true) { // 攻城戦中で旗内なら赤ネームペナルティなし
return;
}
// 最後に殺したキャラがプレイヤーだったら、赤ネームにする
L1PcInstance player = null;
if (lastAttacker instanceof L1PcInstance) {
player = (L1PcInstance) lastAttacker;
}
if (player != null) {
if (getLawful() >= 0 && isPinkName() == false) {
boolean isChangePkCount = false;
// アライメントが30000未満の場合はPKカウント増加
if (player.getLawful() < 30000) {
player.set_PKcount(player.get_PKcount() + 1);
isChangePkCount = true;
}
player.setLastPk();
// アライメント処理
// 公式の発表および各LVでのPKからつじつまの合うように変更
// (PK側のLVに依存し、高LVほどリスクも高い)
// 48あたりで-8kほど DKの時点で10k強
// 60で約20k強 65で30k弱
int lawful;
if (player.getLevel() < 50) {
lawful = -1
* (int) ((Math.pow(player.getLevel(), 2) * 4));
} else {
lawful = -1
* (int) ((Math.pow(player.getLevel(), 3) * 0.08));
}
// もし(元々のアライメント-1000)が計算後より低い場合
// 元々のアライメント-1000をアライメント値とする
// (連続でPKしたときにほとんど値が変わらなかった記憶より)
// これは上の式よりも自信度が低いうろ覚えですので
// 明らかにこうならない!という場合は修正お願いします
if ((player.getLawful() - 1000) < lawful) {
lawful = player.getLawful() - 1000;
}
if (lawful <= -32768) {
lawful = -32768;
}
player.setLawful(lawful);
S_Lawful s_lawful = new S_Lawful(player.getId(), player
.getLawful());
player.sendPackets(s_lawful);
player.broadcastPacket(s_lawful);
if (isChangePkCount && player.get_PKcount() >= 5
&& player.get_PKcount() < 10) {
// あなたのPK回数が%0になりました。回数が%1になると地獄行きです。
player.sendPackets(new S_BlueMessage(551, String
.valueOf(player.get_PKcount()), "10"));
} else if (isChangePkCount && player.get_PKcount() >= 10) {
player.beginHell(true);
}
} else {
setPinkName(false);
}
}
}
}
private void caoPenaltyResult(int count) {
for (int i = 0; i < count; i++) {
L1ItemInstance item = getInventory().CaoPenalty();
if (item != null) {
getInventory().tradeItem(
item,
item.isStackable() ? item.getCount() : 1,
L1World.getInstance().getInventory(getX(), getY(),
getMapId()));
sendPackets(new S_ServerMessage(638,item.getLogName())); // %0を失いました。
} else {
}
}
}
public boolean castleWarResult() {
if (getClanid() != 0 && isCrown()) { // クラン所属中プリのチェック
L1Clan clan = L1World.getInstance().getClan(getClanname());
// 全戦争リストを取得
for (L1War war : L1World.getInstance().getWarList()) {
int warType = war.GetWarType();
boolean isInWar = war.CheckClanInWar(getClanname());
boolean isAttackClan = war.CheckAttackClan(getClanname());
if (getId() == clan.getLeaderId() && // 血盟主で攻撃側で攻城戦中
warType == 1 && isInWar && isAttackClan) {
String enemyClanName = war.GetEnemyClanName(getClanname());
if (enemyClanName != null) {
war.CeaseWar(getClanname(), enemyClanName); // 終結
}
break;
}
}
}
int castleId = 0;
boolean isNowWar = false;
castleId = L1CastleLocation.getCastleIdByArea(this);
if (castleId != 0) { // 旗内に居る
isNowWar = WarTimeController.getInstance().isNowWar(castleId);
}
return isNowWar;
}
public boolean simWarResult(L1Character lastAttacker) {
if (getClanid() == 0) { // クラン所属していない
return false;
}
if (Config.SIM_WAR_PENALTY) { // 模擬戦ペナルティありの場合はfalse
return false;
}
L1PcInstance attacker = null;
String enemyClanName = null;
boolean sameWar = false;
if (lastAttacker instanceof L1PcInstance) {
attacker = (L1PcInstance) lastAttacker;
} else if (lastAttacker instanceof L1PetInstance) {
attacker = (L1PcInstance) ((L1PetInstance) lastAttacker)
.getMaster();
} else if (lastAttacker instanceof L1SummonInstance) {
attacker = (L1PcInstance) ((L1SummonInstance) lastAttacker)
.getMaster();
} else {
return false;
}
// 全戦争リストを取得
for (L1War war : L1World.getInstance().getWarList()) {
L1Clan clan = L1World.getInstance().getClan(getClanname());
int warType = war.GetWarType();
boolean isInWar = war.CheckClanInWar(getClanname());
if (attacker != null && attacker.getClanid() != 0) { // lastAttackerがPC、サモン、ペットでクラン所属中
sameWar = war.CheckClanInSameWar(getClanname(), attacker
.getClanname());
}
if (getId() == clan.getLeaderId() && // 血盟主で模擬戦中
warType == 2 && isInWar == true) {
enemyClanName = war.GetEnemyClanName(getClanname());
if (enemyClanName != null) {
war.CeaseWar(getClanname(), enemyClanName); // 終結
}
}
if (warType == 2 && sameWar) {// 模擬戦で同じ戦争に参加中の場合、ペナルティなし
return true;
}
}
return false;
}
public void resExp() {
int oldLevel = getLevel();
int needExp = ExpTable.getNeedExpNextLevel(oldLevel);
int exp = 0;
if (oldLevel < 45) {
exp = (int) (needExp * 0.05);
} else if (oldLevel == 45) {
exp = (int) (needExp * 0.045);
} else if (oldLevel == 46) {
exp = (int) (needExp * 0.04);
} else if (oldLevel == 47) {
exp = (int) (needExp * 0.035);
} else if (oldLevel == 48) {
exp = (int) (needExp * 0.03);
} else if (oldLevel >= 49) {
exp = (int) (needExp * 0.025);
}
if (exp == 0) {
return;
}
addExp(exp);
}
public void deathPenalty() {
int oldLevel = getLevel();
int needExp = ExpTable.getNeedExpNextLevel(oldLevel);
int exp = 0;
if (oldLevel >= 1 && oldLevel < 11) {
exp = 0;
} else if (oldLevel >= 11 && oldLevel < 45) {
exp = (int) (needExp * 0.1);
} else if (oldLevel == 45) {
exp = (int) (needExp * 0.09);
} else if (oldLevel == 46) {
exp = (int) (needExp * 0.08);
} else if (oldLevel == 47) {
exp = (int) (needExp * 0.07);
} else if (oldLevel == 48) {
exp = (int) (needExp * 0.06);
} else if (oldLevel >= 49) {
exp = (int) (needExp * 0.05);
}
if (exp == 0) {
return;
}
addExp(-exp);
}
private int _originalEr = 0; // ● オリジナルDEX ER補正
public int getOriginalEr() {
return _originalEr;
}
public int getEr() {
if (hasSkillEffect(L1SkillId.STRIKER_GALE)) {
return 0;
}
int er = 0;
if (isKnight()) {
er = getLevel() / 4; // ナイト
} else if (isCrown() || isElf()) {
er = getLevel() / 8; // 君主エルフ
} else if (isDarkelf()) {
er = getLevel() / 6; // ダークエルフ
} else if (isWizard()) {
er = getLevel() / 10; // ウィザード
} else if (isDragonKnight()) {
er = getLevel() / 7; // ドラゴンナイト
} else if (isIllusionist()) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -