From 0985451d7db2800eb1fcf4d2ccaf95d5fcc27f77 Mon Sep 17 00:00:00 2001 From: CharonInferar Date: Sat, 5 Jul 2014 18:10:39 +0200 Subject: [PATCH] Fix for #958, #959 - Added a way to obtain a pet without BEing - Attempted to figure out how to bring up the pet tool bar --- scripts/mobiles/pets/pet_gurreck.py | 1 + scripts/mobiles/pets/pet_merek.py | 38 ++++ .../spawnareas/dantooine_mining_mixed.py | 1 - .../lightsaber/item_color_crystal_02_20.py | 4 - .../tangible/deed/pet_deed/merek_deed.py | 8 +- scripts/radial/npc/pet_radial.py | 18 ++ scripts/radial/npc/untamable.py | 12 + scripts/radial/npc/untamed.py | 18 ++ .../ObjController_02AB.java | 62 +++++ .../ObjController_02AC.java | 61 +++++ .../ObjController_448.java | 64 ++++++ .../ObjectMenuDirty.java | 63 ++++++ src/resources/datatables/PetPCDMapping.java | 213 ++++++++++++++++++ src/resources/objects/SWGList.java | 4 +- .../creature/CreatureMessageBuilder.java | 2 +- .../objects/player/PlayerObject.java | 11 +- src/services/DevService.java | 4 +- src/services/ai/AIActor.java | 6 + src/services/ai/LairActor.java | 9 +- src/services/pet/PetService.java | 184 +++++++++++++-- src/services/spawn/MobileTemplate.java | 9 + src/services/spawn/SpawnService.java | 179 ++++++++++++++- 22 files changed, 933 insertions(+), 38 deletions(-) create mode 100644 scripts/mobiles/pets/pet_merek.py create mode 100644 scripts/radial/npc/pet_radial.py create mode 100644 scripts/radial/npc/untamable.py create mode 100644 scripts/radial/npc/untamed.py create mode 100644 src/protocol/swg/objectControllerObjects/ObjController_02AB.java create mode 100644 src/protocol/swg/objectControllerObjects/ObjController_02AC.java create mode 100644 src/protocol/swg/objectControllerObjects/ObjController_448.java create mode 100644 src/protocol/swg/objectControllerObjects/ObjectMenuDirty.java create mode 100644 src/resources/datatables/PetPCDMapping.java diff --git a/scripts/mobiles/pets/pet_gurreck.py b/scripts/mobiles/pets/pet_gurreck.py index 431ba9e3..12d8213e 100644 --- a/scripts/mobiles/pets/pet_gurreck.py +++ b/scripts/mobiles/pets/pet_gurreck.py @@ -34,5 +34,6 @@ def addTemplate(core): mobileTemplate.setDefaultAttack('creatureMeleeAttack') mobileTemplate.setAttacks(attacks) + mobileTemplate.setPCDTemplate('object/intangible/pet/shared_gurreck_hue.iff') core.spawnService.addMobileTemplate('pet_gurreck', mobileTemplate) return \ No newline at end of file diff --git a/scripts/mobiles/pets/pet_merek.py b/scripts/mobiles/pets/pet_merek.py new file mode 100644 index 00000000..6b0bfe58 --- /dev/null +++ b/scripts/mobiles/pets/pet_merek.py @@ -0,0 +1,38 @@ +import sys +from services.spawn import MobileTemplate +from services.spawn import WeaponTemplate +from resources.datatables import WeaponType +from resources.datatables import Difficulty +from resources.datatables import Options +from java.util import Vector + + +def addTemplate(core): + mobileTemplate = MobileTemplate() + mobileTemplate.setCreatureName('bio_engineered_merek') + mobileTemplate.setLevel(90) + mobileTemplate.setDifficulty(Difficulty.NORMAL) + + mobileTemplate.setMinSpawnDistance(5) + mobileTemplate.setMaxSpawnDistance(10) + mobileTemplate.setDeathblow(True) + mobileTemplate.setSocialGroup("gurreck") + mobileTemplate.setAssistRange(12) + mobileTemplate.setStalker(False) + mobileTemplate.setOptionsBitmask(Options.ATTACKABLE) + + templates = Vector() + templates.add('object/mobile/shared_merek.iff') + mobileTemplate.setTemplates(templates) + + weaponTemplates = Vector() + weapontemplate = WeaponTemplate('object/weapon/melee/unarmed/shared_unarmed_default.iff', WeaponType.UNARMED, 1.0, 6, 'kinetic') + weaponTemplates.add(weapontemplate) + mobileTemplate.setWeaponTemplateVector(weaponTemplates) + + attacks = Vector() + mobileTemplate.setDefaultAttack('creatureMeleeAttack') + mobileTemplate.setAttacks(attacks) + + core.spawnService.addMobileTemplate('pet_merek', mobileTemplate) + return \ No newline at end of file diff --git a/scripts/mobiles/spawnareas/dantooine_mining_mixed.py b/scripts/mobiles/spawnareas/dantooine_mining_mixed.py index 7fd81cad..1d0849db 100644 --- a/scripts/mobiles/spawnareas/dantooine_mining_mixed.py +++ b/scripts/mobiles/spawnareas/dantooine_mining_mixed.py @@ -6,6 +6,5 @@ def addSpawnArea(core): mixedGroups = Vector() mixedGroups.add('piket_plains_walker_group') mixedGroups.add('mixed_lair_group_1') - mixedGroups.add('naboo_starter') core.spawnService.addMixedSpawnArea(mixedGroups, 0, 2355, 1024, 'dantooine') return diff --git a/scripts/object/tangible/component/weapon/lightsaber/item_color_crystal_02_20.py b/scripts/object/tangible/component/weapon/lightsaber/item_color_crystal_02_20.py index 0767f0ac..74d5449e 100644 --- a/scripts/object/tangible/component/weapon/lightsaber/item_color_crystal_02_20.py +++ b/scripts/object/tangible/component/weapon/lightsaber/item_color_crystal_02_20.py @@ -11,10 +11,6 @@ def setup(core, object): object.setStringAttribute('condition', '1000/1000') object.setStringAttribute("@obj_attr_n:color", "Windu's Guile") object.setAttachment('radial_filename', 'item/tunable') -<<<<<<< HEAD - return -======= object.setStringAttribute('@obj_attr_n:crystal_owner", "\\#D1F56F UNTUNED \\#FFFFFF ') return ->>>>>>> origin/master diff --git a/scripts/object/tangible/deed/pet_deed/merek_deed.py b/scripts/object/tangible/deed/pet_deed/merek_deed.py index ccad8904..0eec81fb 100644 --- a/scripts/object/tangible/deed/pet_deed/merek_deed.py +++ b/scripts/object/tangible/deed/pet_deed/merek_deed.py @@ -1,4 +1,10 @@ import sys def setup(core, object): - return \ No newline at end of file + object.setAttachment('radial_filename', 'deeds/petDeed') + return + +def use(core, actor, object): + core.petService.generatePet(actor, object, 'pet_merek', 'object/intangible/pet/shared_merek_hue.iff') + return + \ No newline at end of file diff --git a/scripts/radial/npc/pet_radial.py b/scripts/radial/npc/pet_radial.py new file mode 100644 index 00000000..08dbc86b --- /dev/null +++ b/scripts/radial/npc/pet_radial.py @@ -0,0 +1,18 @@ +from resources.common import RadialOptions +import sys + +def createRadial(core, owner, target, radials): + + radials.add(RadialOptions(0, 45, 1, '@pet/pet_menu:menu_store')) + radials.add(RadialOptions(0, 7, 1, '')) + radials.add(RadialOptions(0, 15, 1, '')) + return + +def handleSelection(core, owner, target, option): + if option == 45 and target: + core.petService.store(owner, target) + elif option == 15 and target: + core.petService.destroy(owner, target) + + return + \ No newline at end of file diff --git a/scripts/radial/npc/untamable.py b/scripts/radial/npc/untamable.py new file mode 100644 index 00000000..420fb6d0 --- /dev/null +++ b/scripts/radial/npc/untamable.py @@ -0,0 +1,12 @@ +from resources.common import RadialOptions +import sys + +def createRadial(core, owner, target, radials): + radials.clear() + + return + +def handleSelection(core, owner, target, option): + + + \ No newline at end of file diff --git a/scripts/radial/npc/untamed.py b/scripts/radial/npc/untamed.py new file mode 100644 index 00000000..c54a242e --- /dev/null +++ b/scripts/radial/npc/untamed.py @@ -0,0 +1,18 @@ +from resources.common import RadialOptions +import sys + +def createRadial(core, owner, target, radials): + radials.clear() + # and check if owner is a beast master! + #owner.sendSystemMessage('UNTAMED', 1) + #if target.getAttachment('tamed'): + radials.add(RadialOptions(0, 159, 3, '@pet/pet_menu:menu_tame')) + + return + +def handleSelection(core, owner, target, option): + + if option == 159: + core.petService.tame(owner, target) + return + \ No newline at end of file diff --git a/src/protocol/swg/objectControllerObjects/ObjController_02AB.java b/src/protocol/swg/objectControllerObjects/ObjController_02AB.java new file mode 100644 index 00000000..0a25266c --- /dev/null +++ b/src/protocol/swg/objectControllerObjects/ObjController_02AB.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package protocol.swg.objectControllerObjects; + +import java.nio.ByteOrder; + +import org.apache.mina.core.buffer.IoBuffer; + +import protocol.swg.ObjControllerMessage; +import resources.datatables.HitType; + +@SuppressWarnings("unused") +public class ObjController_02AB extends ObjControllerObject{ + + private long creatureId; + + public ObjController_02AB(long creatureId) { + this.creatureId = creatureId; + } + + public void deserialize(IoBuffer data) { + + } + + public IoBuffer serialize() { + + IoBuffer result = IoBuffer.allocate(100).order(ByteOrder.LITTLE_ENDIAN); + result.setAutoExpand(true); + + result.putInt(0x02AB); + result.putLong(creatureId); + result.putInt(0); + result.putInt(0x3DCCCCCD); + result.putInt(0x2F2B6FAA); + + int packetSize = result.position(); + result = IoBuffer.allocate(packetSize).put(result.array(), 0, packetSize); + + return result.flip(); + + } + +} diff --git a/src/protocol/swg/objectControllerObjects/ObjController_02AC.java b/src/protocol/swg/objectControllerObjects/ObjController_02AC.java new file mode 100644 index 00000000..b050bee9 --- /dev/null +++ b/src/protocol/swg/objectControllerObjects/ObjController_02AC.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package protocol.swg.objectControllerObjects; + +import java.nio.ByteOrder; + +import org.apache.mina.core.buffer.IoBuffer; + +import protocol.swg.ObjControllerMessage; +import resources.datatables.HitType; + +@SuppressWarnings("unused") +public class ObjController_02AC extends ObjControllerObject{ + + private long creatureId; + + public ObjController_02AC(long creatureId) { + this.creatureId = creatureId; + } + + public void deserialize(IoBuffer data) { + + } + + public IoBuffer serialize() { + + IoBuffer result = IoBuffer.allocate(100).order(ByteOrder.LITTLE_ENDIAN); + result.setAutoExpand(true); + + result.putInt(0x02AB); + result.putLong(creatureId); + result.putInt(0); + result.putInt(0x2F2B6FAA); + + int packetSize = result.position(); + result = IoBuffer.allocate(packetSize).put(result.array(), 0, packetSize); + + return result.flip(); + + } + +} diff --git a/src/protocol/swg/objectControllerObjects/ObjController_448.java b/src/protocol/swg/objectControllerObjects/ObjController_448.java new file mode 100644 index 00000000..f6324a5e --- /dev/null +++ b/src/protocol/swg/objectControllerObjects/ObjController_448.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package protocol.swg.objectControllerObjects; + +import java.nio.ByteOrder; + +import org.apache.mina.core.buffer.IoBuffer; + +import protocol.swg.ObjControllerMessage; + +public class ObjController_448 extends ObjControllerObject { + + private long objectId; + private int commandCRC; + + public ObjController_448(long objectId, int commandCRC) { + this.objectId = objectId; + this.commandCRC = commandCRC; + } + + @Override + public void deserialize(IoBuffer data) { + // TODO Auto-generated method stub + + } + + @Override + public IoBuffer serialize() { + + IoBuffer result = IoBuffer.allocate(45).order(ByteOrder.LITTLE_ENDIAN); + + result.putInt(ObjControllerMessage.START_TASK); + result.putLong(objectId); + result.putInt(0); + result.put((byte) 0); // 0 for no cooldown + result.putInt(0); + result.putInt(0); + result.putInt(0); + result.putInt(commandCRC); + + return result.flip(); + + } + +} diff --git a/src/protocol/swg/objectControllerObjects/ObjectMenuDirty.java b/src/protocol/swg/objectControllerObjects/ObjectMenuDirty.java new file mode 100644 index 00000000..79a0c9c4 --- /dev/null +++ b/src/protocol/swg/objectControllerObjects/ObjectMenuDirty.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package protocol.swg.objectControllerObjects; + +import java.nio.ByteOrder; + +import org.apache.mina.core.buffer.IoBuffer; + +import protocol.swg.ObjControllerMessage; + + + +public class ObjectMenuDirty extends ObjControllerObject { + + private long characterId; + + public ObjectMenuDirty(long characterId){ + this.characterId = characterId; + } + + + + @Override + public void deserialize(IoBuffer buffer) { + + } + + @Override + public IoBuffer serialize() { + IoBuffer result = IoBuffer.allocate(45).order(ByteOrder.LITTLE_ENDIAN); + + result.putInt(0x22B); + result.putLong(characterId); + result.putInt(0); + + return result.flip(); + } + +// 0000: 05 00 46 5E CE 80 1B 00 00 00 2B 02 00 00 7C 0E ..F^......+...|. +// 0010: 31 D6 41 00 00 00 00 00 00 00 1.A....... + + + +} diff --git a/src/resources/datatables/PetPCDMapping.java b/src/resources/datatables/PetPCDMapping.java new file mode 100644 index 00000000..8bc75d1b --- /dev/null +++ b/src/resources/datatables/PetPCDMapping.java @@ -0,0 +1,213 @@ +package resources.datatables; + +import java.util.HashMap; +import java.util.Map; + +public class PetPCDMapping { + public static Map petMap = new HashMap(); + static{ + petMap.put("1", "object/intangible/pet/shared_21b_surgical_droid"); + petMap.put("2", "object/intangible/pet/shared_3po_protocol_droid"); + petMap.put("3", "object/intangible/pet/shared_3po_protocol_droid_crafted"); + petMap.put("4", "object/intangible/pet/shared_3po_protocol_droid_red"); + petMap.put("5", "object/intangible/pet/shared_3po_protocol_droid_silver"); + petMap.put("6", "object/intangible/pet/shared_8d8"); + petMap.put("7", "object/intangible/pet/shared_angler_hue"); + petMap.put("8", "object/intangible/pet/shared_asn_121"); + petMap.put("9", "object/intangible/pet/shared_astromech_waiter"); + petMap.put("10", "object/intangible/pet/shared_bageraset_hue"); + petMap.put("11", "object/intangible/pet/shared_bantha_armored"); + petMap.put("12", "object/intangible/pet/shared_bantha_hue"); + petMap.put("13", "object/intangible/pet/shared_bark_mite_hue"); + petMap.put("14", "object/intangible/pet/shared_battle_droid"); + petMap.put("15", "object/intangible/pet/shared_bearded_jax_hue"); + petMap.put("16", "object/intangible/pet/shared_blistmok"); + petMap.put("17", "object/intangible/pet/shared_blurrg_hue"); + petMap.put("18", "object/intangible/pet/shared_boar_wolf_hue"); + petMap.put("19", "object/intangible/pet/shared_bocatt_hue"); + petMap.put("20", "object/intangible/pet/shared_bolle_bol_hue"); + petMap.put("21", "object/intangible/pet/shared_bolma_hue"); + petMap.put("22", "object/intangible/pet/shared_bolotaur"); + petMap.put("23", "object/intangible/pet/shared_bol_hue"); + petMap.put("24", "object/intangible/pet/shared_bomarr_monk_spider_droid"); + petMap.put("25", "object/intangible/pet/shared_bordok_hue"); + petMap.put("26", "object/intangible/pet/shared_borgle_hue"); + petMap.put("27", "object/intangible/pet/shared_brackaset_hue"); + petMap.put("28", "object/intangible/pet/shared_capper_spineflap_hue"); + petMap.put("29", "object/intangible/pet/shared_carrion_spat_hue"); + petMap.put("30", "object/intangible/pet/shared_choku_hue"); + petMap.put("31", "object/intangible/pet/shared_chuba_hue"); + petMap.put("32", "object/intangible/pet/shared_cll8_binary_load_lifter"); + petMap.put("33", "object/intangible/pet/shared_condor_dragon_hue"); + petMap.put("34", "object/intangible/pet/shared_corellian_butterfly_hue"); + petMap.put("35", "object/intangible/pet/shared_corellian_sand_panther_hue"); + petMap.put("36", "object/intangible/pet/shared_corellian_slice_hound_hue"); + petMap.put("37", "object/intangible/pet/shared_crystal_snake"); + petMap.put("38", "object/intangible/pet/shared_cu_pa_hue"); + petMap.put("39", "object/intangible/pet/shared_cww8_droid_crafted"); + petMap.put("40", "object/intangible/pet/shared_dalyrake_hue"); + petMap.put("41", "object/intangible/pet/shared_darth_maul_probe_droid"); + petMap.put("42", "object/intangible/pet/shared_dewback_hue"); + petMap.put("43", "object/intangible/pet/shared_droideka"); + petMap.put("44", "object/intangible/pet/shared_droid_pet"); + petMap.put("45", "object/intangible/pet/shared_dune_lizard_hue"); + petMap.put("46", "object/intangible/pet/shared_durni_hue"); + petMap.put("47", "object/intangible/pet/shared_dwarf_nuna_hue"); + petMap.put("48", "object/intangible/pet/shared_dwarf_spider_droid"); + petMap.put("49", "object/intangible/pet/shared_dz70_fugitive_tracker_droid"); + petMap.put("50", "object/intangible/pet/shared_eg6_power_droid"); + petMap.put("51", "object/intangible/pet/shared_eg6_power_droid_crafted"); + petMap.put("52", "object/intangible/pet/shared_eopie_hue"); + petMap.put("53", "object/intangible/pet/shared_ev_9d9"); + petMap.put("54", "object/intangible/pet/shared_falumpaset_hue"); + petMap.put("55", "object/intangible/pet/shared_fambaa_hue"); + petMap.put("56", "object/intangible/pet/shared_fanned_rawl_hue"); + petMap.put("57", "object/intangible/pet/shared_flewt_hue"); + petMap.put("58", "object/intangible/pet/shared_flit_hue"); + petMap.put("59", "object/intangible/pet/shared_fynock_hue"); + petMap.put("60", "object/intangible/pet/shared_gackle_bat_hue"); + petMap.put("61", "object/intangible/pet/shared_gaping_spider_hue"); + petMap.put("62", "object/intangible/pet/shared_gcw_atst_familiar_pcd"); + petMap.put("63", "object/intangible/pet/shared_gcw_atxt_familiar_pcd"); + petMap.put("64", "object/intangible/pet/shared_gnort_hue"); + petMap.put("65", "object/intangible/pet/shared_graul_hue"); + petMap.put("66", "object/intangible/pet/shared_gronda_hue"); + petMap.put("67", "object/intangible/pet/shared_gualaar_pcd"); + petMap.put("68", "object/intangible/pet/shared_gualama_hue"); + petMap.put("69", "object/intangible/pet/shared_guardian_mark_ii_crafted"); + petMap.put("70", "object/intangible/pet/shared_gubbur_hue"); + petMap.put("71", "object/intangible/pet/shared_guf_drolg_hue"); + petMap.put("72", "object/intangible/pet/shared_gulginaw_hue"); + petMap.put("73", "object/intangible/pet/shared_gurk_hue"); + petMap.put("74", "object/intangible/pet/shared_gurnaset_hue"); + petMap.put("75", "object/intangible/pet/shared_gurreck_hue"); + petMap.put("76", "object/intangible/pet/shared_hanadak_hue"); + petMap.put("77", "object/intangible/pet/shared_hermit_spider_hue"); + petMap.put("78", "object/intangible/pet/shared_horned_krevol_hue"); + petMap.put("79", "object/intangible/pet/shared_horned_rasp_hue"); + petMap.put("80", "object/intangible/pet/shared_huf_dun_hue"); + petMap.put("81", "object/intangible/pet/shared_huurton_hue"); + petMap.put("82", "object/intangible/pet/shared_ig_assassin_droid"); + petMap.put("83", "object/intangible/pet/shared_ikopi_hue"); + petMap.put("84", "object/intangible/pet/shared_ins_444_crafted"); + petMap.put("85", "object/intangible/pet/shared_ito_interrogator"); + petMap.put("86", "object/intangible/pet/shared_jundak"); + petMap.put("87", "object/intangible/pet/shared_kaadu_hue"); + petMap.put("88", "object/intangible/pet/shared_kai_tok_hue"); + petMap.put("89", "object/intangible/pet/shared_kashyyyk_bantha"); + petMap.put("90", "object/intangible/pet/shared_kima_hue"); + petMap.put("91", "object/intangible/pet/shared_kimogila_hue"); + petMap.put("92", "object/intangible/pet/shared_kliknik_hue"); + petMap.put("93", "object/intangible/pet/shared_krahbu_hue"); + petMap.put("94", "object/intangible/pet/shared_kubaza_beetle"); + petMap.put("95", "object/intangible/pet/shared_kusak_hue"); + petMap.put("96", "object/intangible/pet/shared_kwi_hue"); + petMap.put("97", "object/intangible/pet/shared_langlatch_hue"); + petMap.put("98", "object/intangible/pet/shared_lantern_bird_hue"); + petMap.put("99", "object/intangible/pet/shared_lava_flea"); + petMap.put("100", "object/intangible/pet/shared_le_repair_droid"); + petMap.put("101", "object/intangible/pet/shared_lin_demolitionmech"); + petMap.put("102", "object/intangible/pet/shared_loveday_ewok_cupid"); + petMap.put("103", "object/intangible/pet/shared_loveday_romance_seeker"); + petMap.put("104", "object/intangible/pet/shared_magnaguard"); + petMap.put("105", "object/intangible/pet/shared_malkloc_hue"); + petMap.put("106", "object/intangible/pet/shared_mamien_hue"); + petMap.put("107", "object/intangible/pet/shared_mark_iv_sentry_droid_crafted"); + petMap.put("108", "object/intangible/pet/shared_mawgax_hue"); + petMap.put("109", "object/intangible/pet/shared_merek_hue"); + petMap.put("110", "object/intangible/pet/shared_mining_droid"); + petMap.put("111", "object/intangible/pet/shared_mott_hue"); + petMap.put("112", "object/intangible/pet/shared_mouse_droid"); + petMap.put("113", "object/intangible/pet/shared_mouse_droid_crafted"); + petMap.put("114", "object/intangible/pet/shared_murra_hue"); + petMap.put("115", "object/intangible/pet/shared_mynock_hue"); + petMap.put("116", "object/intangible/pet/shared_narglatch_hue"); + petMap.put("117", "object/intangible/pet/shared_nhelper_droid"); + petMap.put("118", "object/intangible/pet/shared_nuna_hue"); + petMap.put("119", "object/intangible/pet/shared_peko_peko_hue"); + petMap.put("120", "object/intangible/pet/shared_perlek_hue"); + petMap.put("121", "object/intangible/pet/shared_pet_control"); + petMap.put("122", "object/intangible/pet/shared_pet_deed"); + petMap.put("123", "object/intangible/pet/shared_piket_hue"); + petMap.put("124", "object/intangible/pet/shared_pit_droid"); + petMap.put("125", "object/intangible/pet/shared_plumed_rasp_hue"); + petMap.put("126", "object/intangible/pet/shared_probot"); + petMap.put("127", "object/intangible/pet/shared_pugoriss_hue"); + petMap.put("128", "object/intangible/pet/shared_purbole_hue"); + petMap.put("129", "object/intangible/pet/shared_quenker_hue"); + petMap.put("130", "object/intangible/pet/shared_r2"); + petMap.put("131", "object/intangible/pet/shared_r2d2"); + petMap.put("132", "object/intangible/pet/shared_r2_crafted"); + petMap.put("133", "object/intangible/pet/shared_r3"); + petMap.put("134", "object/intangible/pet/shared_r3_crafted"); + petMap.put("135", "object/intangible/pet/shared_r4"); + petMap.put("136", "object/intangible/pet/shared_r4_crafted"); + petMap.put("137", "object/intangible/pet/shared_r5"); + petMap.put("138", "object/intangible/pet/shared_r5_crafted"); + petMap.put("139", "object/intangible/pet/shared_ra7_bug_droid"); + petMap.put("140", "object/intangible/pet/shared_rancor_hue"); + petMap.put("141", "object/intangible/pet/shared_reptilian_flier_hue"); + petMap.put("142", "object/intangible/pet/shared_roba_hue"); + petMap.put("143", "object/intangible/pet/shared_robo_bartender"); + petMap.put("144", "object/intangible/pet/shared_rock_mite_hue"); + petMap.put("145", "object/intangible/pet/shared_ronto_hue"); + petMap.put("146", "object/intangible/pet/shared_salt_mynock_hue"); + petMap.put("147", "object/intangible/pet/shared_sharnaff_hue"); + petMap.put("148", "object/intangible/pet/shared_shaupaut_hue"); + petMap.put("149", "object/intangible/pet/shared_shear_mite_hue"); + petMap.put("150", "object/intangible/pet/shared_skreeg_hue"); + petMap.put("151", "object/intangible/pet/shared_snorbal_hue"); + petMap.put("152", "object/intangible/pet/shared_spined_puc_hue"); + petMap.put("153", "object/intangible/pet/shared_spined_snake_hue"); + petMap.put("154", "object/intangible/pet/shared_squall_hue"); + petMap.put("155", "object/intangible/pet/shared_squill_hue"); + petMap.put("156", "object/intangible/pet/shared_stintaril_hue"); + petMap.put("157", "object/intangible/pet/shared_super_battle_droid"); + petMap.put("158", "object/intangible/pet/shared_super_battle_droid_crafted"); + petMap.put("159", "object/intangible/pet/shared_swirl_prong_hue"); + petMap.put("160", "object/intangible/pet/shared_tanc_mite_hue"); + petMap.put("161", "object/intangible/pet/shared_tanray"); + petMap.put("162", "object/intangible/pet/shared_tauntaun_hue"); + petMap.put("163", "object/intangible/pet/shared_tcg_familiar_hutt_fighter_pcd"); + petMap.put("164", "object/intangible/pet/shared_tcg_familiar_snow_speeder_pcd"); + petMap.put("165", "object/intangible/pet/shared_tcg_familiar_tie_fighter_pcd"); + petMap.put("166", "object/intangible/pet/shared_tcg_familiar_xwing_fighter_pcd"); + petMap.put("167", "object/intangible/pet/shared_tcg_peko_peko_mount"); + petMap.put("168", "object/intangible/pet/shared_thune_hue"); + petMap.put("169", "object/intangible/pet/shared_tip_solicitor_droid"); + petMap.put("170", "object/intangible/pet/shared_torton_hue"); + petMap.put("171", "object/intangible/pet/shared_training_remote"); + petMap.put("172", "object/intangible/pet/shared_tt8l"); + petMap.put("173", "object/intangible/pet/shared_tt8l_y7"); + petMap.put("174", "object/intangible/pet/shared_tulrus"); + petMap.put("175", "object/intangible/pet/shared_tusk_cat_hue"); + petMap.put("176", "object/intangible/pet/shared_tybis_hue"); + petMap.put("177", "object/intangible/pet/shared_union_sentry_droid_crafted"); + petMap.put("178", "object/intangible/pet/shared_varactyl"); + petMap.put("179", "object/intangible/pet/shared_veermok_hue"); + petMap.put("180", "object/intangible/pet/shared_vehicular_prototype"); + petMap.put("181", "object/intangible/pet/shared_vehicular_prototype_bike"); + petMap.put("182", "object/intangible/pet/shared_verne_hue"); + petMap.put("183", "object/intangible/pet/shared_vesp_hue"); + petMap.put("184", "object/intangible/pet/shared_vir_vur_hue"); + petMap.put("185", "object/intangible/pet/shared_voritor_lizard_hue"); + petMap.put("186", "object/intangible/pet/shared_vr_bearded_jax"); + petMap.put("187", "object/intangible/pet/shared_vr_gacklebat"); + petMap.put("188", "object/intangible/pet/shared_vr_mouse_droid"); + petMap.put("189", "object/intangible/pet/shared_vr_mynock"); + petMap.put("190", "object/intangible/pet/shared_vr_nightspider"); + petMap.put("191", "object/intangible/pet/shared_vynock_hue"); + petMap.put("192", "object/intangible/pet/shared_wed_treadwell"); + petMap.put("193", "object/intangible/pet/shared_womp_rat_hue"); + petMap.put("194", "object/intangible/pet/shared_woolamander_hue"); + petMap.put("195", "object/intangible/pet/shared_worrt_hue"); + petMap.put("196", "object/intangible/pet/shared_xandank"); + petMap.put("197", "object/intangible/pet/shared_zucca_boar_hue"); + } + + public PetPCDMapping(){} + + public static String getPCDTemplate(String petTemplate){ + return petMap.get(petTemplate); + } +} diff --git a/src/resources/objects/SWGList.java b/src/resources/objects/SWGList.java index 4160f6c0..8415a535 100644 --- a/src/resources/objects/SWGList.java +++ b/src/resources/objects/SWGList.java @@ -23,6 +23,7 @@ package resources.objects; import java.io.Serializable; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Comparator; import java.util.Iterator; @@ -38,6 +39,7 @@ import java.util.stream.Stream; import org.apache.mina.core.buffer.IoBuffer; import org.python.google.common.collect.Lists; +import engine.resources.common.StringUtilities; import engine.resources.objects.Baseline; import engine.resources.objects.Delta; import engine.resources.objects.IDelta; @@ -305,7 +307,6 @@ public class SWGList implements List, Serializable { synchronized(objectMutex) { if (valid(element)) { E previousElement = list.set(index, element); - queue(item(2, index, Baseline.toBytes(element), true, true)); return previousElement; @@ -340,6 +341,7 @@ public class SWGList implements List, Serializable { this.list = list; updateCounter += list.size(); + StringUtilities.printBytes(newListData); queue(newListData); return true; diff --git a/src/resources/objects/creature/CreatureMessageBuilder.java b/src/resources/objects/creature/CreatureMessageBuilder.java index 8a4a1edb..9604b6df 100644 --- a/src/resources/objects/creature/CreatureMessageBuilder.java +++ b/src/resources/objects/creature/CreatureMessageBuilder.java @@ -399,7 +399,7 @@ public class CreatureMessageBuilder extends TangibleMessageBuilder { buffer.putInt(0xFFFFFFFF); buffer.put((byte) (creature.isRadarVisible() ? 1 : 0)); - buffer.put((byte) 0); // occupyingVehicle (hoth speeder, atat) + buffer.put((byte) 1); // occupyingVehicle (hoth speeder, atat) buffer.put((byte) 0); // no effect for 1? diff --git a/src/resources/objects/player/PlayerObject.java b/src/resources/objects/player/PlayerObject.java index 398605fb..d2f45288 100644 --- a/src/resources/objects/player/PlayerObject.java +++ b/src/resources/objects/player/PlayerObject.java @@ -143,7 +143,7 @@ public class PlayerObject extends IntangibleObject implements Serializable { baseline.put("12", (long) 0); // General? baseline.put("13", 0); // Guild Rank Title? baseline.put("14", (short) 0); // Citizen Rank Title? 6 bytes - baseline.put("speederElevation", 0); + baseline.put("speederElevation", 1); baseline.put("vehicleAttackCommand", ""); return baseline; } @@ -187,8 +187,8 @@ public class PlayerObject extends IntangibleObject implements Serializable { baseline.put("kills", 0); baseline.put("19", 0); baseline.put("pet", (long) 0); - baseline.put("petAbilities", new SWGList(this, 9, 15, false)); - baseline.put("22", (long) 0); // Unknown type currently + baseline.put("petAbilities", new SWGList(this, 9, 21, false)); + baseline.put("activePetAbilities", new SWGList(this, 9, 22, false)); baseline.put("23", (byte) 0); // Seen as 1 or 2 sometimes // Gets set to 0x02 sometimes baseline.put("24", 0); // Seen as 4 baseline.put("25", (long) 0); // Bitmask starts with 0x20 ends with 0x40 @@ -786,6 +786,11 @@ public class PlayerObject extends IntangibleObject implements Serializable { public SWGList getPetAbilities() { return (SWGList) getBaseline(9).get("petAbilities"); } + + @SuppressWarnings("unchecked") + public SWGList getActivePetAbilities() { + return (SWGList) getBaseline(9).get("activePetAbilities"); + } public int getJediState() { return 0; diff --git a/src/services/DevService.java b/src/services/DevService.java index 3700a3da..91b23e8f 100644 --- a/src/services/DevService.java +++ b/src/services/DevService.java @@ -1310,8 +1310,8 @@ public class DevService implements INetworkDispatch { case 131: TangibleObject gurreckDeed = (TangibleObject) core.objectService.createObject("object/tangible/deed/pet_deed/shared_gurreck_deed.iff", planet); inventory.add(gurreckDeed); - TangibleObject droidekaDeed = (TangibleObject) core.objectService.createObject("object/tangible/deed/pet_deed/shared_deed_droideka.iff", planet); - inventory.add(droidekaDeed); + TangibleObject merekDeed = (TangibleObject) core.objectService.createObject("object/tangible/deed/pet_deed/shared_merek_deed.iff", planet); + inventory.add(merekDeed); return; case 140: diff --git a/src/services/ai/AIActor.java b/src/services/ai/AIActor.java index 995a5b3d..b1d391bd 100644 --- a/src/services/ai/AIActor.java +++ b/src/services/ai/AIActor.java @@ -103,8 +103,14 @@ public class AIActor { if(creature.getOption(Options.AGGRESSIVE)) { aggroCheckTask = scheduler.scheduleAtFixedRate(() -> { try { + if(creature == null || creature.getObservers().isEmpty() || creature.isInCombat() || isStalking) return; + if (creature.getAttachment("tamed")!=null){ + boolean tamed = (boolean)creature.getAttachment("tamed"); + if (!tamed) + return; + } creature.getObservers().stream().map(Client::getParent).filter(obj -> obj.inRange(creature.getWorldPosition(), 15)).forEach((obj) -> { if(new Random().nextFloat() <= 0.5 || creature.isInCombat() || isStalking) { /*if(mobileTemplate.isStalker()) { diff --git a/src/services/ai/LairActor.java b/src/services/ai/LairActor.java index 69016ef0..1b7b8970 100644 --- a/src/services/ai/LairActor.java +++ b/src/services/ai/LairActor.java @@ -136,7 +136,14 @@ public class LairActor { Point3D position = SpawnPoint.getRandomPosition(lairObject.getPosition(), 5, 30, lairObject.getPlanetId()); if (creatureTemplates!=null) creatureTemplate = creatureTemplates.get(new Random().nextInt(creatureTemplates.size())); - CreatureObject creature = NGECore.getInstance().spawnService.spawnCreature(creatureTemplate, lairObject.getPlanet().getName(), 0, position.x, position.y, position.z, level); + float babyChance = new Random().nextFloat(); + CreatureObject creature = null; + if (babyChance>0.1){ + creature = NGECore.getInstance().spawnService.spawnCreature(creatureTemplate, lairObject.getPlanet().getName(), 0, position.x, position.y, position.z, level); + } else { + creature = NGECore.getInstance().spawnService.spawnCreatureBaby(creatureTemplate, lairObject.getPlanet().getName(), 0, position.x, position.y, position.z, level); + } + if(creature == null || !creature.isInQuadtree()) { System.out.println("NULL Creature"); continue; diff --git a/src/services/pet/PetService.java b/src/services/pet/PetService.java index 45c9f131..2b4ff898 100644 --- a/src/services/pet/PetService.java +++ b/src/services/pet/PetService.java @@ -24,9 +24,13 @@ package services.pet; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Random; import java.util.concurrent.atomic.LongAdder; import protocol.swg.UpdateContainmentMessage; +import protocol.swg.objectControllerObjects.ObjController_02AB; +import protocol.swg.objectControllerObjects.ObjController_02AC; +import protocol.swg.objectControllerObjects.ObjController_448; import main.NGECore; import resources.common.OutOfBand; import resources.datatables.DisplayType; @@ -131,6 +135,48 @@ public class PetService implements INetworkDispatch { actor.setCalledPet(pet); pcd.setAttachment("companion_RefId", pet.getObjectID()); + +// 0000: 05 00 46 5E CE 80 1B 00 00 00 2B 02 00 00 7C 0E ..F^......+...|. +// 0010: 31 D6 41 00 00 00 00 00 00 00 1.A....... + + + + + + + + + + + + /* CREO3 + 0000: 05 00 53 21 86 12 0B E8 AC 35 52 00 00 00 4F 45 ..S!.....5R...OE + 0010: 52 43 03 16 00 00 00 02 00 0F 00 EC 98 D7 D0 4B RC.............K + 0020: 00 00 00 12 00 00 00 00 10 00 00 00 00 ............. + */ + + // Commandtimer 448 CRC: 90 FA 9D 84 + +// 0000: 05 00 46 5E CE 80 0B 00 00 00 48 04 00 00 EC 98 ..F^......H..... +// 0010: D7 D0 4B 00 00 00 00 00 00 00 00 00 00 00 00 00 ..K............. +// 0020: 00 00 00 00 00 00 00 90 FA 9D 84 ........... + + ObjController_448 objCtrl448 = new ObjController_448(actor.getObjectID(), 0x849DFA90); + actor.getClient().getSession().write(objCtrl448.serialize()); + tools.CharonPacketUtils.printAnalysis(objCtrl448.serialize()); + + + + ObjController_02AB objController = new ObjController_02AB(actor.getObjectID()); + actor.getClient().getSession().write(objController.serialize()); + tools.CharonPacketUtils.printAnalysis(objController.serialize()); + + ObjController_02AC objController2 = new ObjController_02AC(actor.getObjectID()); + actor.getClient().getSession().write(objController2.serialize()); + tools.CharonPacketUtils.printAnalysis(objController2.serialize()); + + + core.mountService.storeAll(actor); // Store all called vehicles //pet.setAttachment("pcdAppearanceFilename", pcd.getTemplateData().getAttribute("appearanceFilename")); @@ -138,33 +184,31 @@ public class PetService implements INetworkDispatch { player.setPet(pet.getObjectID()); //SWGList abilities = player.getPetAbilities(); List abilities = new ArrayList(); - abilities.add("hoth_speeder_up"); // abilities.add("bleedingattack_1"); - abilities.add(""); - abilities.add(""); - abilities.add(""); - abilities.add(""); - abilities.add(""); - abilities.add(""); - abilities.add(""); - abilities.add(""); + abilities.add("bm_pet_attack"); //abilities.add("hoth_speeder_up"); + abilities.add("bm_follow_1"); + abilities.add("bm_stay_1"); + abilities.add("empty"); + abilities.add("empty"); + abilities.add("empty"); + abilities.add("empty"); + abilities.add("toggleBeastDefensive"); + abilities.add("toggleBeastPassive"); //player.setPetAbilities(abilities); //1441 fight hoth speeder player.getPetAbilities().set(abilities); //player.getPetAbilities().addAll(abilities); - -// player.getPetAbilities().add("hoth_speeder_up"); -// player.getPetAbilities().add(""); -// player.getPetAbilities().add(""); -// player.getPetAbilities().add(""); -// player.getPetAbilities().add(""); -// player.getPetAbilities().add(""); -// player.getPetAbilities().add(""); -// player.getPetAbilities().add(""); -// player.getPetAbilities().add(""); -// + + List activeAbilities = new ArrayList(); + activeAbilities.add(""); + activeAbilities.add(""); + activeAbilities.add(""); + activeAbilities.add(""); + activeAbilities.add("toggleBeastPassive"); + player.getActivePetAbilities().set(activeAbilities); pet.setFaction(actor.getFaction()); pet.setFactionStatus(actor.getFactionStatus()); pet.setOwnerId(actor.getObjectID()); + pet.setAttachment("radial_filename", "npc/pet_radial"); AIActor aiActor = (AIActor) pet.getAttachment("AI"); aiActor.setFollowObject(actor); aiActor.setCurrentState(new FollowState()); @@ -659,7 +703,7 @@ public class PetService implements INetworkDispatch { */ public void store(CreatureObject storer, CreatureObject mount) { if (mount == null) { - System.err.println("MountService:store(): mount is null; this should never be the case."); + System.err.println("PetService:store(): mount is null; this should never be the case."); return; } @@ -705,9 +749,13 @@ public class PetService implements INetworkDispatch { public void process(SWGObject pcd) { if (pcd.getAttachment("companion_RefId")!=null){ - if (mount.getObjectID() == ((Long) pcd.getAttachment("companion_RefId"))) { + if (mount.getObjectID() == ((Long) pcd.getAttachment("companion_RefId"))) { + AIActor aiActor = (AIActor) mount.getAttachment("AI"); + aiActor.destroyActor(); + player.setPet(0L); core.objectService.destroyObject((Long) pcd.getAttachment("companion_RefId")); pcd.setAttachment("companion_RefId", null); + System.out.println("STORE called !"); } } } @@ -720,7 +768,7 @@ public class PetService implements INetworkDispatch { return; } - + PlayerObject player = (PlayerObject) actor.getSlottedObject("ghost"); SWGObject datapad = actor.getSlottedObject("datapad"); if (datapad == null) { @@ -740,6 +788,8 @@ public class PetService implements INetworkDispatch { core.objectService.destroyObject(petId); pcd.setAttachment("companion_RefId",null); + player.setPet(0L); + System.out.println("STOREALL called !"); } } } @@ -855,4 +905,92 @@ public class PetService implements INetworkDispatch { call(actor, pet, pcd); } + public void tame(CreatureObject actor, CreatureObject target) { + System.out.println("TAME!"); + + Thread tameThread = new Thread() { + public void run() { + try { + boolean attacking = false; + AIActor aiActor = (AIActor) target.getAttachment("AI"); + actor.sendSystemMessage("Don't be scared.", DisplayType.Broadcast); + OutOfBand oob = OutOfBand.ProsePackage("Don't be scared."); + NGECore.getInstance().chatService.spatialChat(actor, target, "Don't be scared.", (short)0x0, (short)0x0, 1, oob); + Thread.sleep(4000); + actor.sendSystemMessage("Steady.", DisplayType.Broadcast); + OutOfBand oob2 = OutOfBand.ProsePackage("Steady."); + NGECore.getInstance().chatService.spatialChat(actor, target, "Steady.", (short)0x0, (short)0x0, 1, oob2); + Thread.sleep(5000); + + // Chance to attack + float attackChance = new Random().nextFloat(); + if (attackChance<0.25){ + attacking = true; + target.setAttachment("tamed",null); + target.setAttachment("radial_filename", "npc/untamable"); + aiActor.setFollowObject(actor); + aiActor.addDefender(actor); + } + actor.sendSystemMessage("Don't bite me.", DisplayType.Broadcast); + OutOfBand oob3 = OutOfBand.ProsePackage("Don't bite me."); + NGECore.getInstance().chatService.spatialChat(actor, target, "Don't bite me.", (short)0x0, (short)0x0, 1, oob3); + Thread.sleep(3000); + // Chance to attack + attackChance = new Random().nextFloat(); + if (attackChance<0.45 || attacking){ + attacking = true; + target.setAttachment("tamed",null); + aiActor.setFollowObject(actor); + aiActor.addDefender(actor); + actor.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:too_hard"), DisplayType.Broadcast); + target.setAttachment("radial_filename", "npc/untamable"); + return; + } + // Result of taming + float tamingResult = new Random().nextFloat(); + System.out.println("tamingResult " + tamingResult); + if (tamingResult<0.5){ + actor.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:device_added"), DisplayType.Broadcast); + String pcdTemplate = "object/intangible/pet/shared_pet_control.iff"; + SWGObject pcd = core.objectService.createObject(pcdTemplate, actor.getPlanet()); + if (pcd == null) { + return; + } + SWGObject datapad = actor.getSlottedObject("datapad"); + if (datapad == null) { + return; + } + pcd.setAttachment("companion_RefId", target.getObjectID()); + datapad.add(pcd); + + if (target.getOption(Options.AGGRESSIVE)) + target.removeOption(Options.AGGRESSIVE); + if (target.getOption(Options.ATTACKABLE)) + target.removeOption(Options.ATTACKABLE); + + actor.setCalledPet(target); + target.setFaction(actor.getFaction()); + target.setFactionStatus(actor.getFactionStatus()); + target.setOwnerId(actor.getObjectID()); + target.setAttachment("radial_filename", "npc/pet_radial"); + target.setAttachment("tamed", true); + + + aiActor.removeDefender(aiActor.getFollowObject()); // Make sure tamer is no enemy anymore + aiActor.setFollowObject(actor); + aiActor.setCurrentState(new FollowState()); + + } else { + actor.sendSystemMessage(OutOfBand.ProsePackage("@pet/pet_menu:too_hard"), DisplayType.Broadcast); + } + + } catch(InterruptedException v) { + System.out.println(v); + } + } + }; + tameThread.start(); + + } + } diff --git a/src/services/spawn/MobileTemplate.java b/src/services/spawn/MobileTemplate.java index e6b61612..a0ab8683 100644 --- a/src/services/spawn/MobileTemplate.java +++ b/src/services/spawn/MobileTemplate.java @@ -60,6 +60,7 @@ public class MobileTemplate implements Cloneable { private int meatAmount, milkAmount, boneAmount, hideAmount; private int respawnTime = 0; private List lootGroups = new ArrayList(); + private String PCDTemplate=""; public Vector getTemplates() { @@ -351,5 +352,13 @@ public class MobileTemplate implements Cloneable { public void setCustomName(String customName) { this.customName = customName; } + + public String getPCDTemplate() { + return PCDTemplate; + } + + public void setPCDTemplate(String pCDTemplate) { + PCDTemplate = pCDTemplate; + } } diff --git a/src/services/spawn/SpawnService.java b/src/services/spawn/SpawnService.java index 1ba62fe8..f0c542fb 100644 --- a/src/services/spawn/SpawnService.java +++ b/src/services/spawn/SpawnService.java @@ -48,6 +48,7 @@ import resources.objects.tangible.TangibleObject; import resources.objects.weapon.WeaponObject; import services.ai.AIActor; import services.ai.LairActor; +import engine.resources.common.Stf; import engine.resources.container.StaticContainerPermissions; import engine.resources.scene.Planet; import engine.resources.scene.Point3D; @@ -191,7 +192,6 @@ public class SpawnService { creature.setMaxAction((int) (400 + level * 134)); creature.setAction((int) (400 + level * 134)); } else { - System.out.println("HERE"); creature.setMaxHealth(customHealth); creature.setHealth(customHealth); creature.setMaxAction((int) (level * 128)); @@ -212,6 +212,176 @@ public class SpawnService { + if(cell == null) { + core.simulationService.add(creature, x, z, true); + } else { + creature.getPosition().setCell(cell); + cell.add(creature); + } + return creature; + } + + public CreatureObject spawnCreatureBaby(String template, long objectId, String planetName, long cellId, float x, float y, float z, float qW, float qX, float qY, float qZ, short level) { + + Planet planet = core.terrainService.getPlanetByName(planetName); + MobileTemplate mobileTemplate = mobileTemplates.get(template); + if(planet == null || mobileTemplate == null) + return null; + + + + CellObject cell = null; + + if(cellId != 0) { + cell = (CellObject) core.objectService.getObject(cellId); + if(cell == null) + return null; + } + + CreatureObject creature = (CreatureObject) core.objectService.createObject(mobileTemplate.getTemplates().get(new Random().nextInt(mobileTemplate.getTemplates().size())), objectId, planet, new Point3D(x, y, z), new Quaternion(qW, qX, qY, qZ), null, (objectId > 0), true); + + if(creature == null) + return null; + + TangibleObject inventory = (TangibleObject) core.objectService.createObject("object/tangible/inventory/shared_character_inventory.iff", creature.getPlanet()); + inventory.setContainerPermissions(StaticContainerPermissions.STATIC_CONTAINER_PERMISSIONS); + + + /*if(mobileTemplate.getCustomWeapon() != null) { + creature.addObjectToEquipList(mobileTemplate.getCustomWeapon()); + creature.add(mobileTemplate.getCustomWeapon()); + creature.setWeaponId(mobileTemplate.getCustomWeapon().getObjectID()); + }*/ + + if(mobileTemplate.getLootGroups() != null && !mobileTemplate.getLootGroups().isEmpty()) + creature.setLootGroups(mobileTemplate.getLootGroups()); + + creature.setOptionsBitmask(mobileTemplate.getOptionsBitmask()); + creature.setFaction(mobileTemplate.getFaction()); + creature.setFactionStatus(mobileTemplate.getFactionStatus()); + creature.setPvpBitmask(mobileTemplate.getPvpBitmask()); + + if (mobileTemplate.getCustomName()==null){ +// //creature.setStfFilename("mob/creature_names"); // TODO: set other STFs for NPCs other than creatures -> DONE + if (mobileTemplate.getStfFilename()!=null){ +// System.out.println("S4"); +// Stf stf = new Stf(mobileTemplate.getStfFilename()); +// System.out.println("S5"); +// String stfValue = stf.getStfValue(); +// System.out.println("S6"); +// creature.setCustomName(stfValue+" (baby)"); +// + System.out.println("STFNAMECHANGE"); + } + if (mobileTemplate.getCreatureName()!=null){ + String creatureName = mobileTemplate.getCreatureName(); + Stf stf = new Stf("mob/creature_names", 0, creatureName); + String stfValue = stf.getStfValue(); + creature.setCustomName(stfValue+" (baby)"); + } + + } else { + creature.setCustomName(mobileTemplate.getCustomName()+" (baby)"); // For cases where no STF name can be found! + } + creature.setHeight(.25F*mobileTemplate.getScale()); + int difficulty = mobileTemplate.getDifficulty(); + creature.setDifficulty((byte) difficulty); + +// if(level != -1) +// creature.setLevel(level); +// else { +// if (mobileTemplate.getLevel()!=0){ +// level = mobileTemplate.getLevel(); +// creature.setLevel(level); +// } else { +// level = -1; +// } +// } + + creature.setLevel((short)1); + + if (mobileTemplate.getMinLevel()!=0 && mobileTemplate.getMaxLevel()!=0 && level == -1){ + level = (short) (mobileTemplate.getMinLevel() + (new Random().nextInt(mobileTemplate.getMaxLevel()-mobileTemplate.getMinLevel()))); + creature.setLevel(level); + } + + WeaponObject defaultWeapon = null; + Vector weaponTemplates = mobileTemplate.getWeaponTemplateVector(); + int rnd = 0; + + if (weaponTemplates.size() > 0 ) + rnd = new Random().nextInt(weaponTemplates.size()); + + if (weaponTemplates.size() == 0){ + defaultWeapon = (WeaponObject) core.objectService.createObject("object/weapon/creature/shared_creature_default_weapon.iff", creature.getPlanet()); + defaultWeapon.setAttackSpeed(1.0F); + defaultWeapon.setWeaponType(WeaponType.UNARMED); + defaultWeapon.setDamageType("kinetic"); + + defaultWeapon.setMaxRange(5); + } else { + defaultWeapon = (WeaponObject) core.objectService.createObject(weaponTemplates.get(rnd).getTemplate(), creature.getPlanet()); + defaultWeapon.setAttackSpeed(weaponTemplates.get(rnd).getAttackSpeed()); + defaultWeapon.setWeaponType(weaponTemplates.get(rnd).getWeaponType()); + defaultWeapon.setMaxRange(weaponTemplates.get(rnd).getMaxRange()); + defaultWeapon.setDamageType(weaponTemplates.get(rnd).getDamageType()); + } + + if (weaponTemplates.get(rnd).getMinDamage() != 0 && weaponTemplates.get(rnd).getMaxDamage() != 0) { + defaultWeapon.setMaxDamage(weaponTemplates.get(rnd).getMinDamage()); + defaultWeapon.setMinDamage(weaponTemplates.get(rnd).getMaxDamage()); + } else { + defaultWeapon.setMaxDamage(creature.getLevel() * 24); + defaultWeapon.setMinDamage(creature.getLevel() * 22); + } + + creature.addObjectToEquipList(defaultWeapon); + creature.add(defaultWeapon); + creature.setWeaponId(defaultWeapon.getObjectID()); + creature.addObjectToEquipList(inventory); + creature.add(inventory); + + int customHealth = mobileTemplate.getHealth(); + if(difficulty > 0 && customHealth == 0) { + if(difficulty == 1) { + creature.setMaxHealth((int) (400 + level * 134 * 2.5)); + creature.setHealth((int) (400 + level * 134 * 2.5)); + creature.setMaxAction((int) (400 + level * 134 * 2.5)); + creature.setAction((int) (400 + level * 134 * 2.5)); + } else if(difficulty == 2) { + creature.setMaxHealth((int) (400 + level * 134 * 10)); + creature.setHealth((int) (400 + level * 134 * 10)); + creature.setMaxAction((int) (400 + level * 134 * 10)); + creature.setAction((int) (400 + level * 134 * 10)); + } + } else if(difficulty <= 0 && customHealth == 0) { + creature.setMaxHealth((int) (400 + level * 134)); + creature.setHealth((int) (400 + level * 134)); + creature.setMaxAction((int) (400 + level * 134)); + creature.setAction((int) (400 + level * 134)); + } else { + creature.setMaxHealth(customHealth); + creature.setHealth(customHealth); + creature.setMaxAction((int) (level * 128)); + creature.setAction((int) (level * 128)); + } + + if(creature.getLevel() > 16) { + int armor = (creature.getLevel() - 16) * 87; + if(armor > 6000) + armor = 6000; + core.skillModService.addSkillMod(creature, "expertise_innate_protection_all", armor); + } + + // Baby AI + creature.setAttachment("tamed", false); + AIActor actor = new AIActor(creature, creature.getPosition(), scheduler); + creature.setAttachment("AI", actor); + creature.setAttachment("radial_filename", "npc/untamed"); + actor.setMobileTemplate(mobileTemplate); + + + if(cell == null) { core.simulationService.add(creature, x, z, true); } else { @@ -247,6 +417,13 @@ public class SpawnService { return spawnCreature(mobileTemplate, planetName, cellId, x, core.terrainService.getHeight(planet.getID(), x, z), z, 1, 0, 0, 0, level); } + public CreatureObject spawnCreatureBaby(String mobileTemplate, String planetName, long cellId, float x, float y, float z, short level) { + return spawnCreatureBaby(mobileTemplate, planetName, cellId, x, y, z, 1, 0, 0, 0, level); + } + + public CreatureObject spawnCreatureBaby(String template, String planetName, long cellId, float x, float y, float z, float qW, float qX, float qY, float qZ, short level) { + return spawnCreatureBaby(template, 0L, planetName, cellId, x, y, z, qW, qX, qY, qZ, level); + } public LairActor spawnLair(String lairSpawnTemplate, Planet planet, Point3D position, short level) {