天堂技術論壇|天堂私服|天堂1私服|天堂|天堂1

查看: 320|回復: 3

魔法娃娃 : 野狼寶寶

[複製鏈接]

13

主題

13

帖子

41

積分

管理員

Rank: 9Rank: 9Rank: 9

積分
41
發表於 2017-10-31 11:11:14 | 顯示全部樓層 |閱讀模式
1.利用 L1SummonInstance 新增 L1BabyInstance  

package l1j.server.server.model.Instance;  

import java.util.Arrays;  
import java.util.List;  
import java.util.logging.Level;  
import java.util.logging.Logger;  

import l1j.server.server.ActionCodes;  
import l1j.server.server.GeneralThreadPool;  
import l1j.server.server.IdFactory;  
import l1j.server.server.datatables.DropTable;  
import l1j.server.server.datatables.NpcTable;  
import l1j.server.server.model.L1Attack;  
import l1j.server.server.model.L1Character;  
import l1j.server.server.model.L1Inventory;  
import l1j.server.server.model.L1World;  
import l1j.server.server.model.Instance.L1NpcInstance.NpcAI;  
import l1j.server.server.serverpackets.S_AttackPacket;  
import l1j.server.server.serverpackets.S_HPMeter;  
import l1j.server.server.serverpackets.S_PetMenuPacket;  
import l1j.server.server.serverpackets.S_ServerMessage;  
import l1j.server.server.serverpackets.S_SkillSound;  
import l1j.server.server.serverpackets.S_BabyPack;//魔法娃娃功能 by 丫傑  
import l1j.server.server.templates.L1Npc;  

public class L1BabyInstance extends L1NpcInstance {  
private static final long serialVersionUID = 1L;  

private static Logger _log = Logger.getLogger(L1BabyInstance.class  
.getName());  
private final Baby_Timer _timer;  
private int _currentPetStatus;  
private boolean _tamed;  

// ターゲットがいない場合の處理  
@Override  
public boolean noTarget() {  
Random random = new Random();  
//判斷式變更 by 丫傑  
if (_currentPetStatus == 6) {  
if (_tamed) {  
// テイミングモンスター、クリエイトゾンビの解放  
liberate();  
} else {  
// サモンの解散  
Death(null);  
}  
} else if (_master != null && _master.getMapId() == getMapId()) {  
// ●主人を追尾  
if (getLocation().getTileLineDistance(_master.getLocation()) > 2) {  
int dir = moveDirection(_master.getX(), _master.getY());  
setDirectionmove(dir);  
setSleepTime(calcSleepTime(getPassispeed()));  
}  
}  
//判斷式變更 by 丫傑 end  
return false;  
}  

// 1時間計測用のスレッド  
class Baby_Timer implements Runnable {  
@Override  
public void run() {  
for (int Counter = 180; Counter > 0; Counter--) {  
try {  
Thread.sleep(10000);  
} catch (Exception exception) {  
break;  
}  
if (_destroyed) {  
return; // 10秒每に破棄されていないかチェック  
}  
}  
if (_tamed) {  
// テイミングモンスター、クリエイトゾンビの解放  
liberate();  
} else {  
// サモンの解散  
Death(null);  
}  
}  
}  

// 死んでから消えるまでの時間計測用のスレッド  
class Delete_Timer implements Runnable {  
@Override  
public void run() {  
try {  
Thread.sleep(1);//改成1 by 丫傑  
} catch (Exception e) {  
_log.log(Level.SEVERE, e.getLocalizedMessage(), e);  
}  
if (!isDead() || _destroyed) {  
return; // 復活してるか、既に破棄濟みだったら拔け  
}  
delete();  
}  
}  

// サモンモンスター用  
public L1BabyInstance(L1Npc template, L1Character master) {  
super(template);  
setId(IdFactory.getInstance().nextId());  

_timer = new Baby_Timer();  

setMaster(master);  
setX(master.getX() + getRnd().nextInt(5) - 2);  
setY(master.getY() + getRnd().nextInt(5) - 2);  
setMap(master.getMapId());  
setHeading(5);  
setNpcType(12);  

GeneralThreadPool.getInstance().execute(_timer);  
_currentPetStatus = 3;  
_tamed = false;  

L1World.getInstance().storeObject(this);  
L1World.getInstance().addVisibleObject(this);  
L1PcInstance[] players = L1World.getInstance().getVisiblePlayer(this);  
for (L1PcInstance pc : players) {  
if (pc != null) {  
onPerceive(pc);  
}  
}  
master.addPet(this);  
}  

// テイミングモンスター、クリエイトゾンビ用  
public L1BabyInstance(L1NpcInstance target, L1Character master,  
boolean createZombie) {  
super(null);  
setId(IdFactory.getInstance().nextId());  

if (createZombie) // クリエイトゾンビ  
{  
L1Npc template = NpcTable.getInstance().getTemplate(45065).clone(); // 普通のゾンビをベースに作成  
// template.set_level((int) Math.ceil(master.get_level() * 0.66));  
// //  
// 詠唱者の3分の2レベル  
// template.set_hp(template.get_level() * 10); // レベルの10倍  
// template.set_hp(template.get_level() * 5); // レベルの5倍  
// template.set_ac(-(master.get_level() - 10)); // 詠唱者のレベルがAC  
setting_template(template);  
} else // テイミングモンスター  
{  
setting_template(target.getNpcTemplate());  
setCurrentHpDirect(target.getCurrentHp());  
setCurrentMpDirect(target.getCurrentMp());  
}  

_timer = new Baby_Timer();  

setMaster(master);  
setX(target.getX());  
setY(target.getY());  
setMap(target.getMapId());  
setHeading(target.getHeading());  
setNpcType(12);  
setPetcost(6);  

if (target instanceof L1MonsterInstance  
&& !((L1MonsterInstance) target).is_storeDroped()) {  
DropTable.getInstance().setDrop(  
target.getNpcTemplate().get_npcId(), target.getInventory());  
}  
setInventory(target.getInventory());  
target.setInventory(null);  

GeneralThreadPool.getInstance().execute(_timer);  
_currentPetStatus = 3;  
_tamed = true;  

target.deleteMe();  
L1World.getInstance().storeObject(this);  
L1World.getInstance().addVisibleObject(this);  
L1PcInstance players[] = L1World.getInstance().getVisiblePlayer(this);  
for (L1PcInstance pc : players) {  
if (pc != null) {  
onPerceive(pc);  
}  
}  
master.addPet(this);  
}  

@Override  
public void ReceiveDamage(L1Character attacker, int damage) // 攻擊でHPを減らすときはここを使用  
{  
if (getCurrentHp() > 0) {  
if (damage > 0) {  
setHate(attacker, 0); // サモンはヘイト無し  
}  

int newHp = getCurrentHp() - damage;  
if (newHp <= 0) {  
Death(attacker);  
} else {  
setCurrentHp(newHp);  
}  
} else if (!isDead()) // 念のため  
{  
System.out.println("警告︰召喚獸的HP減少處理有不正確的地方。※或者從最初開始HP0");  
Death(attacker);  
}  
}  

public synchronized void Death(L1Character lastAttacker) {  
if (!isDead()) {  
setDead(true);  
setCurrentHp(0);  

getMap().setPassable(getLocation(), true);  

// アイテム解放處理  
L1Inventory targetInventory = _master.getInventory();  
List<L1ItemInstance> items = _inventory.getItems();  
for (L1ItemInstance item : items) {  
if (_master.getInventory().checkAddItem( // 容量重量確認及びメッセージ送信  
item, item.getCount()) == L1Inventory.OK) {  
_inventory  
.tradeItem(item, item.getCount(), targetInventory);  
// \f1%0が%1をくれました。  
((L1PcInstance) _master).sendPackets(new S_ServerMessage(  
143, getName(), item.getLogName()));  
} else { // 持てないので足元に落とす  
targetInventory = L1World.getInstance().getInventory(  
getX(), getY(), getMapId());  
_inventory  
.tradeItem(item, item.getCount(), targetInventory);  
}  
}  

if (_tamed) {  
broadcastPacket(new S_AttackPacket(lastAttacker,  
getId(), ActionCodes.ACTION_Die));  
Delete_Timer delete_timer = new Delete_Timer();  
GeneralThreadPool.getInstance().execute(delete_timer);  
} else {  
delete();  
}  
}  
}  

// オブジェクト消去處理  
public void delete() {  
if (!_tamed) {  
broadcastPacket(new S_SkillSound(getId(), 5936));  
}  
_master.getPetList().remove(getId());  
deleteMe();  
}  

// テイミングモンスター、クリエイトゾンビの時の解放處理  
public void liberate() {  
L1MonsterInstance monster = new L1MonsterInstance(getNpcTemplate());  
monster.setId(IdFactory.getInstance().nextId());  

monster.setX(getX());  
monster.setY(getY());  
monster.setMap(getMapId());  
monster.setHeading(getHeading());  
monster.set_storeDroped(true);  
monster.setInventory(getInventory());  
setInventory(null);  
monster.setCurrentHpDirect(getCurrentHp());  
monster.setCurrentMpDirect(getCurrentMp());  
monster.setExp(0);  

delete();  
L1World.getInstance().storeObject(monster);  
L1World.getInstance().addVisibleObject(monster);  
}  

public void setTarget(L1Character target) {  
if (target != null  
&& (_currentPetStatus == 1 || _currentPetStatus == 2 || _currentPetStatus == 5)) {  
setHate(target, 0);  
if (!isAiRunning()) {  
startAI();  
}  
}  
}  

public void setMasterTarget(L1Character target) {  
if (target != null  
&& (_currentPetStatus == 1 || _currentPetStatus == 5)) {  
setHate(target, 0);  
if (!isAiRunning()) {  
startAI();  
}  
}  
}  

@Override  
public void onAction(L1PcInstance attacker) {  
// XXX:NullPointerException迴避。onActionの引數の型はL1Characterのほうが良い?  
if (attacker == null) {  
return;  
}  
L1Character cha = this.getMaster();  
if (cha == null) {  
return;  
}  
L1PcInstance master = (L1PcInstance) cha;  
if (master.get_isTeleport()) {  
// テレポート處理中  
return;  
}  
if (getZoneType() == 1 || attacker.getZoneType() == 1) {  
// 攻擊される側がセーフティーゾーン  
// 攻擊モーション送信  
L1Attack attack_mortion = new L1Attack(attacker, this);  
attack_mortion.action();  
return;  
}  
// npc.broadcastPacket(new S_AttackPacket(target, npcObjectId,  
// ActionCodes.ACTION_Attack));  

if (attacker.checkNonPvP(attacker, this)) {  
return;  
}  

L1Attack attack = new L1Attack(attacker, this);  
if (attack.calcHit()) {  
attack.calcDamage();  
}  
attack.action();  
attack.commit();  
}  

/*不顯示視窗 by 丫傑@Override  
public void onTalkAction(L1PcInstance player) {  
if (isDead()) {  
return;  
}  
if (_master.equals(player)) {  
player.sendPackets(new S_PetMenuPacket(this, 0));  
}  
}不顯示視窗 by 丫傑*/  

@Override  
public void onFinalAction(L1PcInstance player, String action) {  
int status = ActionType(action);  
if (status == 0) {  
return;  
}  
if (status == 6) {  
if (_tamed) {  
// テイミングモンスター、クリエイトゾンビの解放  
liberate();  
} else {  
// サモンの解散  
Death(null);  
}  
} else {  
// 同じ主人のペットの狀態をすべて更新  
Object[] petList = _master.getPetList().values().toArray();  
for (Object petObject : petList) {  
if (petObject instanceof L1BabyInstance) {  
// サモンモンスター  
L1BabyInstance baby = (L1BabyInstance) petObject;  
baby.set_currentPetStatus(status);  
} else {  
// ペット  
}  
}  
}  
}  

@Override  
public void onPerceive(L1PcInstance perceivedFrom) {  
perceivedFrom.addKnownObject(this);  
perceivedFrom.sendPackets(new S_BabyPack(this, perceivedFrom));//變更成S_BabyPack by 丫傑  
}  

@Override  
public void onItemUse() {  
if (!isActived() && _target != null) {  
// 100%の確率でヘイストポーション使用  
useItem(USEITEM_HASTE, 100);  
}  
if (getCurrentHp() * 100 / getMaxHp() < 40) {  
// HPが40%きったら  
// 100%の確率で回復ポーション使用  
useItem(USEITEM_HEAL, 100);  
}  
}  

@Override  
public void onGetItem(L1ItemInstance item) {  
if (getNpcTemplate().get_digestitem() > 0) {  
setDigestItem(item);  
}  
if (Arrays.binarySearch(healPotions, item.getItem().getItemId()) >= 0) {  
if (getCurrentHp() != getMaxHp()) {  
useItem(USEITEM_HEAL, 100);  
}  
} else if (Arrays  
.binarySearch(haestPotions, item.getItem().getItemId()) >= 0) {  
useItem(USEITEM_HASTE, 100);  
}  
}  

private int ActionType(String action) {  
int status = 0;  
if (action.equalsIgnoreCase("aggressive")) { // 攻擊態勢  
status = 1;  
} else if (action.equalsIgnoreCase("defensive")) { // 防禦態勢  
status = 2;  
} else if (action.equalsIgnoreCase("stay")) { // 休憩  
status = 3;  
} else if (action.equalsIgnoreCase("extend")) { // 配備  
status = 4;  
} else if (action.equalsIgnoreCase("alert")) { // 警戒  
status = 5;  
} else if (action.equalsIgnoreCase("dismiss")) { // 解散  
status = 6;  
}  
return status;  
}  

@Override  
public void setCurrentHp(int i) {  
int currentHp = i;  
if (currentHp >= getMaxHp()) {  
currentHp = getMaxHp();  
}  
setCurrentHpDirect(currentHp);  

if (getMaxHp() > getCurrentHp()) // 自然回復  
{  
if (!_hprRunning && getNpcTemplate().get_hprinterval() > 0  
&& getNpcTemplate().get_hpr() > 0) {  
HprTimer hprTimer = new HprTimer(getNpcTemplate()  
.get_hprinterval(), getNpcTemplate().get_hpr());  
GeneralThreadPool.getInstance().execute(hprTimer);  
}  
}  

if (_master instanceof L1PcInstance) {  
int HpRatio = 100 * currentHp / getMaxHp();  
L1PcInstance Master = (L1PcInstance) _master;  
Master.sendPackets(new S_HPMeter(getId(), HpRatio));  
}  
}  

@Override  
public void setCurrentMp(int i) {  
int currentMp = i;  
if (currentMp >= getMaxMp()) {  
currentMp = getMaxMp();  
}  
setCurrentMpDirect(currentMp);  
if (getMaxMp() > getCurrentMp()) // 自然回復  
{  
if (!_mprRunning && getNpcTemplate().get_mprinterval() > 0  
&& getNpcTemplate().get_mpr() > 0) {  
MprTimer mprTimer = new MprTimer(getNpcTemplate()  
.get_mprinterval(), getNpcTemplate().get_mpr());  
GeneralThreadPool.getInstance().execute(mprTimer);  
}  
}  
}  

public void set_currentPetStatus(int i) {  
_currentPetStatus = i;  
if (_currentPetStatus == 5) {  
setHomeX(getX());  
setHomeY(getY());  
}  

if (_currentPetStatus == 3) {  
allTargetClear();  
} else {  
if (!isAiRunning()) {  
startAI();  
}  
}  
}  

public int get_currentPetStatus() {  
return _currentPetStatus;  
}  
}  



2.利用 S_SummonPack 新增 S_BabyPack  

/*  
* 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.  
*  
*
*/  

package l1j.server.server.serverpackets;  

import java.util.logging.Logger;  

import l1j.server.server.Opcodes;  
import l1j.server.server.model.Instance.L1PcInstance;  
import l1j.server.server.model.Instance.L1BabyInstance;//魔法娃娃功能 by 丫傑  

// Referenced classes of package l1j.server.server.serverpackets:  
// ServerBasePacket, S_BabyPack  

public class S_BabyPack extends ServerBasePacket {  

private static final String _S__1F_BABYPACK = "[S] S_BabyPack";  
private static Logger _log = Logger.getLogger(S_BabyPack.class.getName());  

private byte[] _byte = null;  

public S_BabyPack(L1BabyInstance pet, L1PcInstance player) {  
/*  
* int addbyte = 0; int addbyte1 = 1; int addbyte2 = 13; int setting =  
* 4;  
*/  
writeC(Opcodes.S_OPCODE_CHARPACK);  
writeH(pet.getX());  
writeH(pet.getY());  
writeD(pet.getId());  
writeH(pet.getGfxId()); // SpriteID in List.spr  
writeC(pet.getStatus()); // Modes in List.spr  
writeC(pet.getHeading());  
writeC(pet.getNpcType()); // ??(Bright) - 0~15  
writeC(1); // スピード - 0:normal, 1:fast 改成加速狀態 by 丫傑  
// 2:slow  
writeD(0);  
writeH(0);  
writeS(pet.getNameId());  
writeS(pet.getTitle());  
writeC(4); // シシニテ - 0:mob,item(atk pointer), 1:poisoned(), 改成4 by 丫傑  
// 2:invisable(), 4:pc, 8:cursed(), 16:brave(),  
// 32:??, 64:??(??), 128:invisable but name  
writeD(0); // ??  
writeS(null); // ??  
writeS(pet.getMaster() != null ? pet.getMaster().getName() : "");  
writeC(0); // ??  
// HPのパーセント  
/*不顯示血條 by 丫傑if (pet.getMaster() != null  
&& pet.getMaster().getId() == player.getId()) {  
writeC(100 * pet.getCurrentHp() / pet.getMaxHp());  
} else {不顯示血條 by 丫傑*/  
writeC(0xFF);  
/*不顯示血條 by 丫傑}不顯示血條 by 丫傑*/  
writeC(0);  
writeC(pet.getLevel()); // PC = 0, Mon = Lv  
writeC(0);  
writeC(0xFF);  
writeC(0xFF);  
}  

@Override  
public byte[] getContent() {  
if (_byte == null) {  
_byte = _bao.toByteArray();  
}  

return _byte;  
}  

public String getType() {  
return _S__1F_BABYPACK;  
}  

}  



3.L1Attack.java  

import l1j.server.server.model.Instance.L1BabyInstance;//魔法娃娃特殊功能 by 丫傑  


在  
if (_diceDaggerEffect) { // ダイスダガー  
dmg = _diceDaggerDamage;  
}  

底下新增  

//魔法娃娃:野狼寶寶增加傷害 by 丫傑  
if (_pc.getInventory().checkItem(300005) && (_random.nextInt(100) + 1) > 95) {  
Object[] petList = _pc.getPetList().values().toArray();  
for (Object BabyObject : petList) {  
if ((BabyObject instanceof L1BabyInstance) && ((L1BabyInstance) BabyObject).getNpcTemplate().get_npcId() == 200004) {  
byte c = (byte)(_random.nextInt(2) + 1);  
L1BabyInstance baby = (L1BabyInstance) BabyObject;  
switch(c) {  
case 1: {  
baby.broadcastPacket(new S_AttackMissPacket(baby, baby.getId(), 66));  
}break;  
case 2: {  
baby.broadcastPacket(new S_AttackMissPacket(baby, baby.getId(), 67));  
}break;  
}  
baby.broadcastPacket(new S_SkillSound(_pc.getId(), 6319));  
dmg += 15;  
}  
}  
}  
//魔法娃娃:野狼寶寶增加傷害 by 丫傑 end  



在  
dmg -= calcNpcDamageReduction();  

底下新增  

//魔法娃娃:野狼寶寶增加傷害 by 丫傑  
if (_pc.getInventory().checkItem(300005) && (_random.nextInt(100) + 1) > 95) {  
Object[] petList = _pc.getPetList().values().toArray();  
for (Object BabyObject : petList) {  
if ((BabyObject instanceof L1BabyInstance) && ((L1BabyInstance) BabyObject).getNpcTemplate().get_npcId() == 200004) {  
byte c = (byte)(_random.nextInt(2) + 1);  
L1BabyInstance baby = (L1BabyInstance) BabyObject;  
switch(c) {  
case 1: {  
baby.broadcastPacket(new S_AttackMissPacket(baby, baby.getId(), 66));  
}break;  
case 2: {  
baby.broadcastPacket(new S_AttackMissPacket(baby, baby.getId(), 67));  
}break;  
}  
baby.broadcastPacket(new S_SkillSound(_pc.getId(), 6319));  
dmg += 15;  
}  
}  
}  
//魔法娃娃:野狼寶寶增加傷害 by 丫傑 end  



將  
if (_targetNpc.hasSkillEffect(EARTH_BIND)) {  
dmg = 0;  
}  

改成  

if (_targetNpc.hasSkillEffect(EARTH_BIND) || (_targetNpc instanceof L1BabyInstance)) {  
dmg = 0;  
}  



4.L1Magic.java  

import l1j.server.server.model.Instance.L1BabyInstance;//魔法娃娃特殊功能 by 丫傑  

將  
if (_targetNpc.hasSkillEffect(EARTH_BIND)) {  
dmg = 0;  
}  

改成  

if (_targetNpc.hasSkillEffect(EARTH_BIND) || (_targetNpc instanceof L1BabyInstance)) {  
dmg = 0;  
}  

將  
_targetNpc.ReceiveDamage(_pc, damage);  

改成  

//修正補血出現血條 by srwh  
if (!(_targetNpc instanceof L1BabyInstance)) {  
_targetNpc.ReceiveDamage(_pc, damage);  
} else {  
}  
//修正補血出現血條 by srwh end  



5.C_RequestItemUSe.java  

import l1j.server.server.datatables.NpcTable;//召喚怪物功能 by 丫傑  
import l1j.server.server.model.Instance.L1BabyInstance;//召喚魔法娃娃功能 by 丫傑  
import l1j.server.server.templates.L1Npc;//召喚怪物功能 by 丫傑  

在  
else if (itemId == 40615) { // 影の神殿2階の鍵  
if ((pc.getX() >= 32701 && pc.getX() <= 32705)  
&& (pc.getY() >= 32894 && pc.getY() <= 32898)  
&& pc.getMapId() == 522) { // 影の神殿1F  
L1Teleport.teleport(pc, ((L1EtcItem) l1iteminstance  
.getItem()).get_locx(),  
((L1EtcItem) l1iteminstance.getItem())  
.get_locy(),  
((L1EtcItem) l1iteminstance.getItem())  
.get_mapid(), 5, true);  
} else {  
// \f1何も起きませんでした。  
pc.sendPackets(new S_ServerMessage(79, ""));  
}  
}  

底下新增  

else if (itemId == 300005) {//魔法娃娃:野狼寶寶 by 丫傑  
if (pc.getMap().isRecallPets() || pc.isGm()) {  
int petcost = 0;  
Object[] petlist = pc.getPetList().values().toArray();  
for (Object pet : petlist) {  
// 現在のペットコスト  
petcost += ((L1NpcInstance) pet).getPetcost();  
}  
if (petcost == 0) { // 1匹も所属NPCがいなければ実行  
L1Npc npcTemp = NpcTable.getInstance().getTemplate(200004);  
L1BabyInstance baby = new L1BabyInstance(npcTemp, pc);  
baby.setPetcost(pc.getCha() + 127); // 精霊の他にはNPCを所属させられない  
baby.broadcastPacket(new S_SkillSound(baby.getId(), 5935));  
baby.set_currentPetStatus(1);  
} else {//解除魔法娃娃功能 by 丫傑  
Object[] petList = pc.getPetList().values().toArray();  
for (Object BabyObject : petList) {  
if (BabyObject instanceof L1BabyInstance) {  
L1BabyInstance baby = (L1BabyInstance) BabyObject;  
int bid = baby.getNpcTemplate().get_npcId();  
if (bid == 200004) {  
baby.set_currentPetStatus(6);  
}  
}  
}  
}//解除魔法娃娃功能 by 丫傑 end  
} else {  
// \f1何も起きませんでした。  
pc.sendPackets(new S_ServerMessage(79, ""));  
}  
}
回復

使用道具 舉報

您需要登錄後才可以回帖 登錄 | 立即註冊

本版積分規則

天堂私服發佈

QQ:

228606881

工作時間

12:00-24:00

快速回復 返回頂部 返回列表