int CreatureTemplateManager::addTemplate(lua_State* L) { if (checkArgumentCount(L, 2) == 1) { instance()->error("incorrect number of arguments passed to CreatureTemplateManager::addTemplate"); ERROR_CODE = INCORRECT_ARGUMENTS; return 0; } String ascii = lua_tostring(L, -2); uint32 crc = (uint32) ascii.hashCode(); LuaObject obj(L); CreatureTemplate* newTemp = new CreatureTemplate(); newTemp->setTemplateName(ascii); newTemp->readObject(&obj); if (instance()->hashTable.containsKey(crc)) { luaL_where (L, 2); String luaMethodName = lua_tostring(L, -1); lua_pop(L, 1); instance()->error("overwriting mobile " + ascii + " with " + luaMethodName); ERROR_CODE = DUPLICATE_MOBILE; } CreatureTemplateManager::instance()->hashTable.put(crc, newTemp); int count = loadedMobileTemplates.increment(); if (ConfigManager::instance()->isProgressMonitorActivated() && !DEBUG_MODE) printf("\r\tLoading mobile templates: [%d] / [?]\t", count); return 0; }
CreatureObject* CreatureManagerImplementation::spawnCreatureAsBaby(uint32 templateCRC, float x, float z, float y, uint64 parentID) { CreatureTemplate* creoTempl = creatureTemplateManager->getTemplate(templateCRC); if (creoTempl == NULL || creoTempl->getTame() <= 0) return NULL; CreatureObject* creo = NULL; String templateToSpawn = getTemplateToSpawn(templateCRC); uint32 objectCRC = templateToSpawn.hashCode(); creo = createCreature(objectCRC, false, templateCRC); if (creo != NULL && creo->isCreature()) { Creature* creature = cast<Creature*>(creo); creature->loadTemplateDataForBaby(creoTempl); } else { error("could not spawn template " + templateToSpawn + " as baby."); creo = NULL; } placeCreature(creo, x, z, y, parentID); if (creo != NULL && creo->isAiAgent()) cast<AiAgent*>(creo)->activateLoad(""); else { error("could not spawn template " + templateToSpawn + " as baby with AI."); creo = NULL; } return creo; }
bool CreatureManagerImplementation::createCreatureChildrenObjects(CreatureObject* creature, uint32 templateCRC, bool persistent, uint32 mobileTemplateCRC) { if (creature->hasSlotDescriptor("default_weapon")) { uint32 defaultWeaponCRC = 0; if (creature->isNonPlayerCreatureObject()) { defaultWeaponCRC = STRING_HASHCODE("object/weapon/melee/unarmed/unarmed_default.iff"); } else { defaultWeaponCRC = STRING_HASHCODE("object/weapon/creature/creature_default_weapon.iff"); } ManagedReference<SceneObject*> defaultWeapon = zoneServer->createObject(defaultWeaponCRC, persistent); ManagedReference<SceneObject*> otherWeapon; if(mobileTemplateCRC != 0) { CreatureTemplate* creoTempl = creatureTemplateManager->getTemplate(mobileTemplateCRC); if(creoTempl != NULL && creoTempl->getDefaultWeapon() != ""){ uint32 otherWeaponCRC = String(creoTempl->getDefaultWeapon()).hashCode(); otherWeapon = zoneServer->createObject(otherWeaponCRC, persistent); } } if(otherWeapon != NULL) { if (defaultWeapon != NULL && defaultWeapon->isPersistent()) { Locker clocker(defaultWeapon, creature); defaultWeapon->destroyObjectFromDatabase(true); } defaultWeapon = otherWeapon; } if (defaultWeapon == NULL) { error("could not create creature default weapon"); return false; } Locker clocker(defaultWeapon, creature); creature->transferObject(defaultWeapon, 4); } if (creature->hasSlotDescriptor("inventory")) { Reference<SceneObject*> creatureInventory = zoneServer->createObject(STRING_HASHCODE("object/tangible/inventory/creature_inventory.iff"), persistent); if (creatureInventory == NULL) { error("could not create creature inventory"); return false; } Locker clocker(creatureInventory, creature); creatureInventory->setContainerDefaultDenyPermission(ContainerPermissions::MOVECONTAINER); creatureInventory->setContainerDenyPermission("owner", ContainerPermissions::MOVECONTAINER); creatureInventory->setContainerInheritPermissionsFromParent(false); creature->transferObject(creatureInventory, 4); } return true; }
TEST_F(LuaMobileTest, LuaMobileTemplatesTest) { CreatureTemplateManager::DEBUG_MODE = 1; // Verify that all mobiles load ASSERT_EQ(CreatureTemplateManager::instance()->loadTemplates(), 0); // Verify loot group map loads LootGroupMap* lootGroupMap = LootGroupMap::instance(); ASSERT_EQ(lootGroupMap->initialize(), 0); HashTableIterator<uint32, Reference<CreatureTemplate*> > iter = CreatureTemplateManager::instance()->iterator(); while (iter.hasNext()) { CreatureTemplate* creature = iter.next(); std::string templateName( creature->getTemplateName().toCharArray() ); // Verify loot group percentages LootGroupCollection* groupCollection = creature->getLootGroups(); if( groupCollection->count() > 0 ){ for( int i = 0; i < groupCollection->count(); i++ ){ LootGroupCollectionEntry* collectionEntry = groupCollection->get(i); LootGroups* groups = collectionEntry->getLootGroups(); if( groups->count() > 0){ int totalChance = 0; for( int j = 0; j < groups->count(); j++ ){ LootGroupEntry* lootGroup = groups->get(j); totalChance += lootGroup->getLootChance(); // Verify loot group is configured correctly LootGroupTemplate* foundGroup = lootGroupMap->getLootGroupTemplate( lootGroup->getLootGroupName() ); std::string groupName( lootGroup->getLootGroupName().toCharArray() ); EXPECT_TRUE( foundGroup != NULL ) << "Loot group " << groupName << " from " << templateName << " was not found in LootGroupMap"; } EXPECT_EQ( 10000000, totalChance ) << "Loot groups total chance is incorrect " << templateName; } } } // Verify weapon groups exist Vector<String> weapons = creature->getWeapons(); for (int i = 0; i < weapons.size(); i++) { String weaponGroup = weapons.get(i); std::string groupName( weaponGroup.toCharArray() ); Vector<String> group = CreatureTemplateManager::instance()->getWeapons(weaponGroup); EXPECT_TRUE( group.size() > 0 ) << "Weapon group " << groupName << " from " << templateName << " was not found in weaponMap"; } } }
String CreatureManagerImplementation::getTemplateToSpawn(uint32 templateCRC) { String templateToSpawn = ""; CreatureTemplate* creoTempl = creatureTemplateManager->getTemplate(templateCRC); Vector<String> objTemps = creoTempl->getTemplates(); if (objTemps.size() > 0) { uint32 randomTemp = System::random(objTemps.size() - 1); templateToSpawn = objTemps.get(randomTemp); } else { StringBuffer errMsg; errMsg << "could not spawn creature... no object templates in script " << creoTempl->getTemplateName(); //error(errMsg.toString()); } return templateToSpawn; }
int HuntingMissionObjectiveImplementation::notifyObserverEvent(MissionObserver* observer, uint32 eventType, Observable* observable, ManagedObject* arg1, int64 arg2) { ManagedReference<MissionObject* > mission = this->mission.get(); if (eventType == ObserverEventType::KILLEDCREATURE) { if (cast<CreatureObject*>(observable) != getPlayerOwner().get()) return 0; CreatureObject* creature = cast<CreatureObject*>(arg1); AiAgent* agent = cast<AiAgent*>(creature); if (agent == NULL) return 0; CreatureTemplate* creatureTemplate = agent->getCreatureTemplate(); if (creatureTemplate == NULL) return 0; String temp1 = mission->getTemplateString1(); String temp2 = mission->getTemplateString2(); if (creatureTemplate->getTemplateName() == temp1 || creatureTemplate->getTemplateName() == temp2) { targetsKilled--; if (targetsKilled <= 0) { complete(); return 1; } StringIdChatParameter message("mission/mission_generic", "hunting_kills_remaining"); message.setDI(targetsKilled); message.setTO(mission->getTargetName()); getPlayerOwner().get()->sendSystemMessage(message); } } return 0; }
void DnaManager::generateSample(Creature* creature, CreatureObject* player,int quality){ if (quality < 0 || quality > 7) { return; } Locker lock(creature,player); CreatureTemplate* creatureTemplate = dynamic_cast<CreatureTemplate*>(creature->getCreatureTemplate()); int ferocity = creatureTemplate->getFerocity(); int cl = creature->getLevel(); int cle = Genetics::hitChanceToValue(creature->getChanceHit(),quality); int cou = Genetics::meatTypeToValue(creature->getMeatType(),quality); int dep = Genetics::dietToValue(creature->getDiet(),quality); int dex = Genetics::hamToValue(creature->getMaxHAM(3),quality); int end = Genetics::accelerationToValue(creature->getWalkAcceleration(),quality); int fie = Genetics::ferocityToValue(ferocity,quality); int frt = Genetics::resistanceToValue(creature->getEffectiveResist(),creature->getArmor(),quality); int har = Genetics::hamToValue(creature->getMaxHAM(0),quality); int ite = Genetics::hamToValue(creature->getMaxHAM(6),quality); int pow = Genetics::damageToValue((creature->getDamageMax() + creature->getDamageMin())/2,quality); ManagedReference<SceneObject*> inventory = player->getSlottedObject("inventory"); if (inventory->hasFullContainerObjects()) { StringIdChatParameter err("survey", "no_inv_space"); player->sendSystemMessage(err); player->setPosture(CreaturePosture::UPRIGHT, true); return; } // We should now have enough to generate a sample ManagedReference<DnaComponent*> prototype = player->getZoneServer()->createObject(qualityTemplates.get(quality), 1).castTo<DnaComponent*>(); if (prototype == NULL) { return; } Locker clocker(prototype); // Check Here for unique npcs StringId* nameId = creature->getObjectName(); if (nameId->getFile().isEmpty() || nameId->getStringID().isEmpty()) { prototype->setSource(creature->getCreatureName().toString()); } else { prototype->setSource(nameId->getFullPath()); } prototype->setQuality(quality); prototype->setLevel(cl); String serial = player->getZoneServer()->getCraftingManager()->generateSerial(); prototype->setSerialNumber(serial); prototype->setStats(cle,end,fie,pow,ite,cou,dep,dex,frt,har); prototype->setStun(creatureTemplate->getStun()); prototype->setKinetic(creatureTemplate->getKinetic()); prototype->setEnergy(creatureTemplate->getEnergy()); prototype->setBlast(creatureTemplate->getBlast()); prototype->setHeat(creatureTemplate->getHeat()); prototype->setCold(creatureTemplate->getCold()); prototype->setElectric(creatureTemplate->getElectricity()); prototype->setAcid(creatureTemplate->getAcid()); prototype->setSaber(creatureTemplate->getLightSaber()); prototype->setRanged(creatureTemplate->getWeapons().size() > 0); prototype->setArmorRating(creatureTemplate->getArmor()); if (creatureTemplate->isSpecialProtection(WeaponObject::STUN)) prototype->setSpecialResist(WeaponObject::STUN); if (creatureTemplate->isSpecialProtection(WeaponObject::KINETIC)) prototype->setSpecialResist(WeaponObject::KINETIC); if (creatureTemplate->isSpecialProtection(WeaponObject::ENERGY)) prototype->setSpecialResist(WeaponObject::ENERGY); if (creatureTemplate->isSpecialProtection(WeaponObject::BLAST)) prototype->setSpecialResist(WeaponObject::BLAST); if (creatureTemplate->isSpecialProtection(WeaponObject::HEAT)) prototype->setSpecialResist(WeaponObject::HEAT); if (creatureTemplate->isSpecialProtection(WeaponObject::COLD)) prototype->setSpecialResist(WeaponObject::COLD); if (creatureTemplate->isSpecialProtection(WeaponObject::ELECTRICITY)) prototype->setSpecialResist(WeaponObject::ELECTRICITY); if (creatureTemplate->isSpecialProtection(WeaponObject::ACID)) prototype->setSpecialResist(WeaponObject::ACID); if (creatureTemplate->isSpecialProtection(WeaponObject::LIGHTSABER)) prototype->setSpecialResist(WeaponObject::LIGHTSABER); CreatureAttackMap* attackMap = creatureTemplate->getAttacks(); if (attackMap->size() > 0) { prototype->setSpecialAttackOne(String(attackMap->getCommand(0))); if(attackMap->size() > 1) { prototype->setSpecialAttackTwo(String(attackMap->getCommand(1))); } } Locker locker(inventory); if (inventory->transferObject(prototype, -1, true, false)) { inventory->broadcastObject(prototype, true); } else { prototype->destroyObjectFromDatabase(true); } }
bool LairObserverImplementation::checkForNewSpawns(TangibleObject* lair, TangibleObject* attacker, bool forceSpawn) { if (lair->getZone() == NULL) return false; if (spawnedCreatures.size() >= lairTemplate->getSpawnLimit() && !lairTemplate->hasBossMobs()) return false; if (forceSpawn) { spawnNumber++; } else if (getMobType() == LairTemplate::NPC) { return false; } else { int conditionDamage = lair->getConditionDamage(); int maxCondition = lair->getMaxCondition(); switch (spawnNumber) { case 0: spawnNumber++; break; case 1: if (conditionDamage > (maxCondition / 10)) { spawnNumber++; } else { return false; } break; case 2: if (conditionDamage > (maxCondition / 2)) { spawnNumber++; } else { return false; } break; case 3: if (lairTemplate->hasBossMobs() && conditionDamage > ((maxCondition * 9) / 10)) { spawnNumber++; } else { return false; } break; default: return false; break; } } VectorMap<String, int> objectsToSpawn; // String mobileTemplate, int number to spawn if (spawnNumber == 4) { if (System::random(100) > 9) return false; VectorMap<String, int>* mobs = lairTemplate->getBossMobiles(); for (int i = 0; i < mobs->size(); i++) { objectsToSpawn.put(mobs->elementAt(i).getKey(), mobs->elementAt(i).getValue()); } } else { Vector<String>* mobiles = lairTemplate->getWeightedMobiles(); int amountToSpawn = 0; if (getMobType() == LairTemplate::CREATURE) { amountToSpawn = System::random(3) + ((lairTemplate->getSpawnLimit() / 3) - 2); } else { amountToSpawn = System::random(lairTemplate->getSpawnLimit() / 2) + (lairTemplate->getSpawnLimit() / 2); } if (amountToSpawn < 1) amountToSpawn = 1; for (int i = 0; i < amountToSpawn; i++) { int num = System::random(mobiles->size() - 1); String mob = mobiles->get(num); if (objectsToSpawn.contains(mob)) { int value = objectsToSpawn.get(mob); objectsToSpawn.drop(mob); objectsToSpawn.put(mob, value + 1); } else { objectsToSpawn.put(mob, 1); } } } for(int i = 0; i < objectsToSpawn.size(); ++i) { if (spawnNumber != 4 && spawnedCreatures.size() >= lairTemplate->getSpawnLimit()) return true; String templateToSpawn = objectsToSpawn.elementAt(i).getKey(); int numberToSpawn = objectsToSpawn.get(templateToSpawn); CreatureTemplate* creatureTemplate = CreatureTemplateManager::instance()->getTemplate(templateToSpawn); if (creatureTemplate == NULL) continue; float tamingChance = creatureTemplate->getTame(); CreatureManager* creatureManager = lair->getZone()->getCreatureManager(); for (int j = 0; j < numberToSpawn; j++) { float x = lair->getPositionX() + (size - System::random(size * 20) / 10.0f); float y = lair->getPositionY() + (size - System::random(size * 20) / 10.0f); float z = lair->getZone()->getHeight(x, y); ManagedReference<CreatureObject*> creo = NULL; if (creatureManager->checkSpawnAsBaby(tamingChance, babiesSpawned, 500)) { creo = creatureManager->spawnCreatureAsBaby(templateToSpawn.hashCode(), x, z, y); babiesSpawned++; } if (creo == NULL) creo = creatureManager->spawnCreatureWithAi(templateToSpawn.hashCode(), x, z, y); if (creo == NULL) continue; if (!creo->isAiAgent()) { error("spawned non player creature with template " + templateToSpawn); } else { AiAgent* ai = cast<AiAgent*>( creo.get()); //Locker clocker(npc, lair); ai->setDespawnOnNoPlayerInRange(false); ai->setHomeLocation(x, z, y); ai->setRespawnTimer(0); ai->setHomeObject(lair); spawnedCreatures.add(creo); } } } if (spawnNumber == 4) { Reference<LairAggroTask*> task = new LairAggroTask(lair, attacker, _this.get(), true); task->schedule(1000); } return objectsToSpawn.size() > 0; }
void CreatureManagerImplementation::tame(Creature* creature, CreatureObject* player, bool force) { Zone* zone = creature->getZone(); if (zone == NULL || !creature->isCreature()) return; if(player->getPendingTask("tame_pet") != NULL) { player->sendSystemMessage("You are already taming a pet"); return; } if(player->getPendingTask("call_pet") != NULL) { player->sendSystemMessage("You cannot tame a pet while another is being called"); return; } if (!creature->canTameMe(player) || !creature->isAttackableBy(player)) { player->sendSystemMessage("@pet/pet_menu:sys_cant_tame"); // You can't tame that return; } CreatureTemplate* creatureTemplate = creature->getCreatureTemplate(); if (creatureTemplate == NULL) return; int templateLevel = creatureTemplate->getLevel(); int maxLevelofPets = player->getSkillMod("tame_level"); if (!player->hasSkill("outdoors_creaturehandler_novice") || (templateLevel > maxLevelofPets)) { player->sendSystemMessage("@pet/pet_menu:sys_lack_skill"); // You lack the skill to be able to tame that creature. return; } if ((creature->isVicious() && player->getSkillMod("tame_aggro") < 1) || creature->getChanceToTame(player) <= 0) { player->sendSystemMessage("@pet/pet_menu:sys_lack_skill"); // You lack the skill to be able to tame that creature. return; } ManagedReference<SceneObject*> datapad = player->getSlottedObject("datapad"); if (datapad == NULL) return; if (datapad->getContainerObjectsSize() >= datapad->getContainerVolumeLimit()) { player->sendSystemMessage("@faction_recruiter:datapad_full"); // Your datapad is full. You must first free some space. return; } ManagedReference<PlayerManager*> playerManager = zoneServer->getPlayerManager(); int numberStored = 0; int maxStoredPets = playerManager->getBaseStoredCreaturePets() + player->getSkillMod("stored_pets"); for (int i = 0; i < datapad->getContainerObjectsSize(); ++i) { ManagedReference<SceneObject*> object = datapad->getContainerObject(i); if (object != NULL && object->isPetControlDevice()) { PetControlDevice* device = cast<PetControlDevice*>( object.get()); if (device->getPetType() == PetManager::CREATUREPET) { if (++numberStored >= maxStoredPets) { player->sendSystemMessage("@pet/pet_menu:sys_too_many_stored"); // There are too many pets stored in this container. Release some of them to make room for more. return; } } } } ManagedReference<PlayerObject*> ghost = player->getPlayerObject(); int currentlySpawned = 0; int spawnedLevel = 0; int level = creature->getLevel(); int maxPets = player->getSkillMod("keep_creature"); for (int i = 0; i < ghost->getActivePetsSize(); ++i) { ManagedReference<AiAgent*> object = ghost->getActivePet(i); if (object != NULL) { ManagedReference<PetControlDevice*> pcd = object->getControlDevice().get().castTo<PetControlDevice*>(); if (pcd == NULL || pcd->getPetType() != PetManager::CREATUREPET) { continue; } if (++currentlySpawned >= maxPets) { player->sendSystemMessage("@pet/pet_menu:too_many"); // You can't control any more pets. Store one first return; } spawnedLevel += object->getLevel(); if ((spawnedLevel + level) >= maxLevelofPets) { player->sendSystemMessage("Taming this pet would exceed your control level ability."); return; } } } if (force && !ghost->isPrivileged()) force = false; ChatManager* chatManager = player->getZoneServer()->getChatManager(); chatManager->broadcastMessage(player, "@hireling/hireling:taming_1"); // Easy. Locker clocker(creature); int mask = creature->getPvpStatusBitmask(); creature->setPvpStatusBitmask(0, true); if (creature->isAiAgent()) { AiAgent* agent = cast<AiAgent*>(creature); agent->activateLoad("wait"); } ManagedReference<TameCreatureTask*> task = new TameCreatureTask(creature, player, mask, force); player->addPendingTask("tame_pet", task, 8000); }
void PetControlDeviceImplementation::callObject(CreatureObject* player) { if (player->isInCombat() || player->isDead() || player->isIncapacitated() || player->getPendingTask("tame_pet") != NULL) { player->sendSystemMessage("@pet/pet_menu:cant_call"); // You cannot call this pet right now. return; } if (player->isRidingMount()) { player->sendSystemMessage("@pet/pet_menu:mounted_call_warning"); // You cannot call a pet while mounted or riding a vehicle. return; } if (player->getParent() != NULL) { ManagedReference<SceneObject*> strongRef = player->getRootParent(); ManagedReference<BuildingObject*> building = NULL; if (strongRef != NULL) building = strongRef.castTo<BuildingObject*>(); if (building == NULL || building->isPrivateStructure()) { player->sendSystemMessage("@pet/pet_menu:private_house"); // You cannot call pets in a private building. return; } } if (!isASubChildOf(player)) return; ManagedReference<TangibleObject*> controlledObject = this->controlledObject.get(); if (controlledObject == NULL || !controlledObject->isAiAgent()) return; ManagedReference<AiAgent*> pet = cast<AiAgent*>(controlledObject.get()); ManagedReference<PlayerObject*> ghost = player->getPlayerObject(); if (ghost->hasActivePet(pet)) return; FrsManager* frsManager = server->getZoneServer()->getFrsManager(); if (frsManager->isFrsEnabled() && frsManager->isPlayerInEnclave(player)) { player->sendSystemMessage("@pet/pet_menu:cant_call"); // You cannot call this pet right now. return; } if (vitality <= 0) { player->sendSystemMessage("@pet/pet_menu:dead_pet"); // This pet is dead. Select DESTROY from the radial menu to delete this pet control device. return; } if (!pet->getCooldownTimerMap()->isPast("call_cooldown")) { if (petType == PetManager::DROIDPET) player->sendSystemMessage("@pet/droid_modules:droid_maint_on_maint_run"); //You cannot call that droid. It is currently on a maintenance run. else player->sendSystemMessage("@pet/pet_menu:cant_call"); // cant call pet right now return; } assert(pet->isLockedByCurrentThread()); unsigned int petFaction = pet->getFaction(); if (petFaction != 0) { if (player->getFaction() == 0) { StringIdChatParameter message("@faction_perk:prose_be_declared"); // You must be declared to a faction to use %TT. message.setTT(pet->getDisplayedName()); player->sendSystemMessage(message); return; } if (player->getFaction() != petFaction || player->getFactionStatus() == FactionStatus::ONLEAVE) { StringIdChatParameter message("@faction_perk:prose_be_declared_faction"); // You must be a declared %TO to use %TT. message.setTO(pet->getFactionString()); message.setTT(pet->getDisplayedName()); player->sendSystemMessage(message); return; } } if(player->getPendingTask("call_pet") != NULL) { StringIdChatParameter waitTime("pet/pet_menu", "call_delay_finish_pet"); // Already calling a Pet: Call will be finished in %DI seconds. AtomicTime nextExecution; Core::getTaskManager()->getNextExecutionTime(player->getPendingTask("call_pet"), nextExecution); int timeLeft = (nextExecution.getMiliTime() / 1000) - System::getTime(); waitTime.setDI(timeLeft); player->sendSystemMessage(waitTime); return; } if (!growPet(player)) return; if (petType == PetManager::CREATUREPET && !isValidPet(pet)) { ManagedReference<SuiMessageBox*> box = new SuiMessageBox(player,SuiWindowType::PET_FIX_DIALOG); box->setCallback(new PetFixSuiCallback(player->getZoneServer(), _this.getReferenceUnsafeStaticCast())); box->setPromptText("@bio_engineer:pet_sui_text"); box->setPromptTitle("@bio_engineer:pet_sui_title"); box->setOkButton(true,"@bio_engineer:pet_sui_fix_stats"); box->setCancelButton(true,"@bio_engineer:pet_sui_abort"); box->setOtherButton(true,"@bio_engineer:pet_sui_fix_level"); box->setUsingObject(_this.getReferenceUnsafeStaticCast()); player->getPlayerObject()->addSuiBox(box); player->sendMessage(box->generateMessage()); return; } int currentlySpawned = 0; int spawnedLevel = 0; int maxPets = 1; int maxLevelofPets = 10; int level = pet->getLevel(); if (pet->getCreatureTemplate() == NULL) { player->sendSystemMessage("Invalid creature to spawn!"); // Old npc without a npc template? return; } if (petType == PetManager::CREATUREPET) { ManagedReference<Creature*> creaturePet = cast<Creature*>(pet.get()); if (creaturePet == NULL) return; bool ch = player->hasSkill("outdoors_creaturehandler_novice"); if (ch) { maxPets = player->getSkillMod("keep_creature"); maxLevelofPets = player->getSkillMod("tame_level"); } if (creaturePet->getAdultLevel() > maxLevelofPets) { player->sendSystemMessage("@pet/pet_menu:control_exceeded"); // Calling this pet would exceed your Control Level ability. return; } if (creaturePet->isVicious() && (player->getSkillMod("tame_aggro") <= 0 || !ch)) { player->sendSystemMessage("@pet/pet_menu:lack_skill"); // You lack the skill to call a pet of this type. return; } } else if (petType == PetManager::FACTIONPET){ maxPets = 3; } for (int i = 0; i < ghost->getActivePetsSize(); ++i) { ManagedReference<AiAgent*> object = ghost->getActivePet(i); if (object != NULL) { if (object->isCreature() && petType == PetManager::CREATUREPET) { CreatureTemplate* activePetTemplate = object->getCreatureTemplate(); if (activePetTemplate == NULL || activePetTemplate->getTemplateName() == "at_st") continue; if (++currentlySpawned >= maxPets) { player->sendSystemMessage("@pet/pet_menu:at_max"); // You already have the maximum number of pets of this type that you can call. return; } spawnedLevel += object->getLevel(); if ((spawnedLevel + level) > maxLevelofPets) { player->sendSystemMessage("@pet/pet_menu:control_exceeded"); // Calling this pet would exceed your Control Level ability. return; } } else if (object->isNonPlayerCreatureObject() && petType == PetManager::FACTIONPET) { if (++currentlySpawned >= maxPets) { player->sendSystemMessage("@pet/pet_menu:at_max"); // You already have the maximum number of pets of this type that you can call. return; } } else if (object->isCreature() && petType == PetManager::FACTIONPET) { CreatureTemplate* activePetTemplate = object->getCreatureTemplate(); CreatureTemplate* callingPetTemplate = pet->getCreatureTemplate(); if (activePetTemplate == NULL || callingPetTemplate == NULL || activePetTemplate->getTemplateName() != "at_st") continue; if (++currentlySpawned >= maxPets || (activePetTemplate->getTemplateName() == "at_st" && callingPetTemplate->getTemplateName() == "at_st")) { player->sendSystemMessage("@pet/pet_menu:at_max"); // You already have the maximum number of pets of this type that you can call. return; } } else if (object->isDroidObject() && petType == PetManager::DROIDPET) { if (++currentlySpawned >= maxPets) { player->sendSystemMessage("@pet/pet_menu:at_max"); // You already have the maximum number of pets of this type that you can call. return; } } } } ManagedReference<TradeSession*> tradeContainer = player->getActiveSession(SessionFacadeType::TRADE).castTo<TradeSession*>(); if (tradeContainer != NULL) { server->getZoneServer()->getPlayerManager()->handleAbortTradeMessage(player); } if (player->getCurrentCamp() == NULL && player->getCityRegion() == NULL) { Reference<CallPetTask*> callPet = new CallPetTask(_this.getReferenceUnsafeStaticCast(), player, "call_pet"); StringIdChatParameter message("pet/pet_menu", "call_pet_delay"); // Calling pet in %DI seconds. Combat will terminate pet call. message.setDI(15); player->sendSystemMessage(message); player->addPendingTask("call_pet", callPet, 15 * 1000); if (petControlObserver == NULL) { petControlObserver = new PetControlObserver(_this.getReferenceUnsafeStaticCast()); petControlObserver->deploy(); } player->registerObserver(ObserverEventType::STARTCOMBAT, petControlObserver); } else { // Player is in a city or camp, spawn pet immediately if( player->getCooldownTimerMap() == NULL ) return; // Check cooldown if( !player->getCooldownTimerMap()->isPast("petCallOrStoreCooldown") ){ player->sendSystemMessage("@pet/pet_menu:cant_call_1sec"); //"You cannot CALL for 1 second." return; } spawnObject(player); // Set cooldown player->getCooldownTimerMap()->updateToCurrentAndAddMili("petCallOrStoreCooldown", 1000); // 1 sec } EnqueuePetCommand* enqueueCommand = new EnqueuePetCommand(pet, String("petFollow").toLowerCase().hashCode(), String::valueOf(player->getObjectID()), player->getObjectID(), 1); enqueueCommand->execute(); }
TEST_F(LuaMobileTest, LuaMobileTemplatesTest) { CreatureTemplateManager::DEBUG_MODE = 1; // Verify that all mobiles load ASSERT_EQ(CreatureTemplateManager::instance()->loadTemplates(), 0); // Verify loot group map loaded ASSERT_EQ(LootGroupMap::ERROR_CODE, 0); // Verify factions load FactionManager::instance()->loadData(); ASSERT_FALSE(FactionManager::instance()->getFactionMap()->isEmpty()); // Load Templates ASSERT_TRUE( TemplateManager::instance() != NULL ); if( TemplateManager::instance()->loadedTemplatesCount == 0 ){ TemplateManager::instance()->loadLuaTemplates(); ASSERT_EQ(TemplateManager::ERROR_CODE, 0); } // verify DNA manager loads DnaManager::instance()->loadSampleData(); ASSERT_TRUE( DnaManager::instance() != NULL); // Test Creature Templates HashTableIterator<uint32, Reference<CreatureTemplate*> > creatureIterator = CreatureTemplateManager::instance()->iterator(); while (creatureIterator.hasNext()) { CreatureTemplate* creature = creatureIterator.next(); std::string templateName( creature->getTemplateName().toCharArray() ); //Verify non-empty objectName is a valid string String objName = creature->getObjectName(); if (!objName.isEmpty()) { std::string name = objName.toCharArray(); EXPECT_TRUE( mobNames.contains(objName) ) << "Mobile " << templateName << " has invalid objectName: " << name; } // Check configured templates Vector<String> objTemps = creature->getTemplates(); EXPECT_FALSE( objTemps.isEmpty() ) << "Mobile " << templateName << " does not have any templates configured"; int objectType = 0; for( int j=0; j< objTemps.size(); j++ ){ SharedObjectTemplate* templateData = templateManager->getTemplate(objTemps.get(j).hashCode()); std::string objName = objTemps.get(j).toCharArray(); EXPECT_TRUE( templateData != NULL ) << "Mobile " << templateName << " has invalid template configured: " << objName; // Check Template Genetics math to find invalid mobs if (templateData != NULL) { SharedCreatureObjectTemplate* creoData = dynamic_cast<SharedCreatureObjectTemplate*> (templateData); if (creoData != NULL) { } } if (objectType == 0) { objectType = templateData->getGameObjectType(); } } // Verify that control device template is valid String controlDeviceTemplate = creature->getControlDeviceTemplate(); if (!controlDeviceTemplate.isEmpty()) { SharedObjectTemplate* controlDeviceTemplateData = templateManager->getTemplate(controlDeviceTemplate.hashCode()); EXPECT_TRUE( controlDeviceTemplateData != NULL ) << "Control device template " << controlDeviceTemplate.toCharArray() << " from " << templateName << " does not exist."; EXPECT_TRUE( controlDeviceTemplate.beginsWith("object/intangible/pet/") ) << "Control device template " << controlDeviceTemplate.toCharArray() << " from " << templateName << " is not a pet/droid control device template."; } // Verify that faction is valid String faction = creature->getFaction(); if (!faction.isEmpty()) { EXPECT_TRUE( FactionManager::instance()->isFaction(faction) ) << "Faction, " << faction.toCharArray() << ", from mobile template " << templateName << " does not exist."; } // Verify level int level = creature->getLevel(); EXPECT_TRUE( level > 0 ) << "Level is not a positive value on mobile: " << templateName; // Verify hit chance float hitChance = creature->getChanceHit(); EXPECT_TRUE( hitChance > 0 ) << "ChanceHit is not a positive value on mobile: " << templateName; // Verify xp int xp = creature->getBaseXp(); EXPECT_TRUE( xp >= 0 ) << "Xp has a negative value on mobile: " << templateName; // Verify damage int minDamage = creature->getDamageMin(); int maxDamage = creature->getDamageMax(); EXPECT_TRUE( minDamage > 0 ) << "Min damage is not a positive value on mobile: " << templateName; EXPECT_TRUE( maxDamage >= minDamage ) << "Max damage is lower than min damage on mobile: " << templateName; // Verify HAM int minHam = creature->getBaseHAM(); int maxHam = creature->getBaseHAMmax(); EXPECT_TRUE( minHam > 0 ) << "Base ham is not a positive value on mobile: " << templateName; EXPECT_TRUE( maxHam >= minHam ) << "Base ham max is lower than base ham on mobile: " << templateName; // Verify armor int armor = creature->getArmor(); EXPECT_TRUE( armor >= 0 && armor <= 3 ) << "Armor is not a valid value on mobile: " << templateName; // Verify resists float kinetic = creature->getKinetic(); EXPECT_TRUE( kinetic >= -1 && kinetic <= 200 ) << "Kinetic resist is not a valid value on mobile: " << templateName; float energy = creature->getEnergy(); EXPECT_TRUE( energy >= -1 && energy <= 200 ) << "Energy resist is not a valid value on mobile: " << templateName; float electricity = creature->getElectricity(); EXPECT_TRUE( electricity >= -1 && electricity <= 200 ) << "Electricity resist is not a valid value on mobile: " << templateName; float stun = creature->getStun(); EXPECT_TRUE( stun >= -1 && stun <= 200 ) << "Stun resist is not a valid value on mobile: " << templateName; float blast = creature->getBlast(); EXPECT_TRUE( blast >= -1 && blast <= 200 ) << "Blast resist is not a valid value on mobile: " << templateName; float heat = creature->getHeat(); EXPECT_TRUE( heat >= -1 && heat <= 200 ) << "Heat resist is not a valid value on mobile: " << templateName; float cold = creature->getCold(); EXPECT_TRUE( cold >= -1 && cold <= 200 ) << "Cold resist is not a valid value on mobile: " << templateName; float acid = creature->getAcid(); EXPECT_TRUE( acid >= -1 && acid <= 200 ) << "Acid resist is not a valid value on mobile: " << templateName; float lightSaber = creature->getLightSaber(); EXPECT_TRUE( lightSaber >= -1 && lightSaber <= 200 ) << "LightSaber resist is not a valid value on mobile: " << templateName; // Verify creature resources String meat = creature->getMeatType(); float meatMax = creature->getMeatMax(); if (!meat.isEmpty()) { String meatResources = "meat_domesticated,meat_wild,meat_herbivore,meat_carnivore,meat_reptilian,meat_avian,meat_insect"; StringTokenizer tokenizer(meatResources); tokenizer.setDelimeter(","); bool match = false; String token; while (tokenizer.hasMoreTokens()) { tokenizer.getStringToken(token); if (meat == token) match = true; } EXPECT_TRUE( match ) << "Meat type on mobile " << templateName << " is not a valid meat resource"; EXPECT_TRUE( meatMax > 0 ) << "Meat amount on mobile " << templateName << " is zero."; } else { EXPECT_TRUE( meatMax == 0 ) << "MeatAmount is not zero yet has no type defined on mobile " << templateName; } String hide = creature->getHideType(); float hideMax = creature->getHideMax(); if (!hide.isEmpty()) { String hideResources = "hide_bristley,hide_leathery,hide_scaley,hide_wooly"; StringTokenizer tokenizer(hideResources); tokenizer.setDelimeter(","); bool match = false; String token; while (tokenizer.hasMoreTokens()) { tokenizer.getStringToken(token); if (hide == token) match = true; } EXPECT_TRUE( match ) << "Hide type on mobile " << templateName << " is not a valid hide resource"; EXPECT_TRUE( hideMax > 0 ) << "Hide amount on mobile " << templateName << " is zero."; } else { EXPECT_TRUE( hideMax == 0 ) << "HideAmount is not zero yet has no type defined on mobile " << templateName; } String bone = creature->getBoneType(); float boneMax = creature->getBoneMax(); if (!bone.isEmpty()) { String boneResources = "bone_avian,bone_mammal"; StringTokenizer tokenizer(boneResources); tokenizer.setDelimeter(","); bool match = false; String token; while (tokenizer.hasMoreTokens()) { tokenizer.getStringToken(token); if (bone == token) match = true; } EXPECT_TRUE( match ) << "Bone type on mobile " << templateName << " is not a valid bone resource"; EXPECT_TRUE( boneMax > 0 ) << "Bone amount on mobile " << templateName << " is zero."; } else { EXPECT_TRUE( boneMax == 0 ) << "BoneAmount is not zero yet has no type defined on mobile " << templateName; } String milk = creature->getMilkType(); float milkMax = creature->getMilk(); if (!milk.isEmpty()) { String milkResources = "milk_domesticated,milk_wild"; StringTokenizer tokenizer(milkResources); tokenizer.setDelimeter(","); bool match = false; String token; while (tokenizer.hasMoreTokens()) { tokenizer.getStringToken(token); if (milk == token) match = true; } EXPECT_TRUE( match ) << "Milk type on mobile " << templateName << " is not a valid milk resource"; EXPECT_TRUE( milkMax > 0 ) << "Milk amount on mobile " << templateName << " is zero."; } else { EXPECT_TRUE( milkMax == 0 ) << "Milk is not zero yet has no type defined on mobile " << templateName; } // Verify taming chance float tamingChance = creature->getTame(); EXPECT_TRUE( tamingChance >= 0 && tamingChance <= 1 ) << "Taming chance is not a valid value on mobile: " << templateName; // Verify diet on creatures if (boneMax > 0 || hideMax > 0 || meatMax > 0 || milkMax > 0 || tamingChance > 0) { uint32 diet = creature->getDiet(); EXPECT_TRUE( diet != 0 ) << "Diet is NONE on creature type mobile " << templateName; } // Verify scale float scale = creature->getScale(); EXPECT_TRUE( scale > 0 ) << "Scale is not a positive value on mobile: " << templateName; // Verify PACK mobs have a social group uint32 creatureBitmask = creature->getCreatureBitmask(); String socialGroup = creature->getSocialGroup(); if (creatureBitmask & CreatureFlag::PACK) { EXPECT_FALSE( socialGroup.isEmpty() ) << "Social group is empty on pack mobile: " << templateName; } // Verify loot group percentages LootGroupCollection* groupCollection = creature->getLootGroups(); if( groupCollection->count() > 0 ){ for( int i = 0; i < groupCollection->count(); i++ ){ LootGroupCollectionEntry* collectionEntry = groupCollection->get(i); LootGroups* groups = collectionEntry->getLootGroups(); if( groups->count() > 0){ int totalChance = 0; for( int j = 0; j < groups->count(); j++ ){ LootGroupEntry* lootGroup = groups->get(j); totalChance += lootGroup->getLootChance(); // Verify loot group is configured correctly LootGroupTemplate* foundGroup = lootGroupMap->getLootGroupTemplate( lootGroup->getLootGroupName() ); std::string groupName( lootGroup->getLootGroupName().toCharArray() ); EXPECT_TRUE( foundGroup != NULL ) << "Loot group " << groupName << " from " << templateName << " was not found in LootGroupMap"; } EXPECT_EQ( 10000000, totalChance ) << "Loot groups total chance is incorrect " << templateName; } } } // Verify weapon groups exist Vector<String> weapons = creature->getWeapons(); for (int i = 0; i < weapons.size(); i++) { String weaponGroup = weapons.get(i); std::string groupName( weaponGroup.toCharArray() ); Vector<String> group = CreatureTemplateManager::instance()->getWeapons(weaponGroup); EXPECT_TRUE( group.size() > 0 ) << "Weapon group " << groupName << " from " << templateName << " was not found in weaponMap"; } // Verify conversation template exist, and the mob has converse option bit uint32 convoTemplate = creature->getConversationTemplate(); uint32 optionsBitmask = creature->getOptionsBitmask(); if (convoTemplate != 0) { ConversationTemplate* convoTemp = CreatureTemplateManager::instance()->getConversationTemplate(convoTemplate); EXPECT_TRUE( convoTemp != NULL ) << "Conversation template from " << templateName << " was not found."; EXPECT_TRUE( optionsBitmask & OptionBitmask::CONVERSE ) << templateName << " has a convo template but not the CONVERSE options bit."; } // Verify that mobs with converse option bit have a convo template if (optionsBitmask & OptionBitmask::CONVERSE) { EXPECT_TRUE( convoTemplate != 0 ) << templateName << " has the CONVERSE options bit but not a convo template."; } // Verify that outfits exist String outfit = creature->getOutfit(); if (!outfit.isEmpty()) { MobileOutfitGroup* outfitGroup = CreatureTemplateManager::instance()->getMobileOutfitGroup(outfit); EXPECT_TRUE( outfitGroup != NULL ) << "Outfit group " << outfit.toCharArray() << " from " << templateName << " was not found."; } // Verify attacks are valid commands CreatureAttackMap* cam = creature->getAttacks(); for (int i = 0; i < cam->size(); i++) { String commandName = cam->getCommand(i); EXPECT_TRUE( commandName.isEmpty() || commandConfigManager->contains(commandName) ) << "Attack: " << commandName.toCharArray() << " is not a valid command in mobile template: " << templateName; } // Very attackable npcs uint32 pvpBitmask = creature->getPvpBitmask(); if ((pvpBitmask & CreatureFlag::ATTACKABLE) && objectType == 1025) { // Verify attackable npcs have attacks EXPECT_TRUE( cam->size() > 0 ) << "Attackable npc " << templateName << " does not have attacks."; } } // Test Lair Templates HashTableIterator<uint32, Reference<LairTemplate*> > lairIterator = CreatureTemplateManager::instance()->lairTemplateIterator(); while (lairIterator.hasNext()) { LairTemplate* lair = lairIterator.next(); std::string templateName( lair->getName().toCharArray() ); // Verify that mobiles exist and that their weighting is positive VectorMap<String, int>* mobiles = lair->getMobiles(); for (int i = 0; i < mobiles->size(); i++) { int weighting = mobiles->elementAt(i).getValue(); String mobile = mobiles->elementAt(i).getKey(); std::string mobName = mobile.toCharArray(); EXPECT_TRUE( CreatureTemplateManager::instance()->getTemplate(mobile) != NULL ) << "Mobile " << mobName << " in lair template " << templateName << " does not exist"; EXPECT_TRUE( weighting > 0 ) << "Mobile " << mobName << " in lair template " << templateName << " has a non positive weighting"; } // Verify that boss mobiles exist and that their count is positive VectorMap<String, int>* bossMobiles = lair->getBossMobiles(); for (int i = 0; i < bossMobiles->size(); i++) { int count = bossMobiles->elementAt(i).getValue(); String bossMob = bossMobiles->elementAt(i).getKey(); std::string bossName = bossMob.toCharArray(); EXPECT_TRUE( CreatureTemplateManager::instance()->getTemplate(bossMob) != NULL ) << "Boss mobile " << bossName << " in lair template " << templateName << " does not exist"; EXPECT_TRUE( count > 0 ) << "Boss mobile " << bossName << " in lair template " << templateName << " has a non positive spawn count"; } // Verify spawn limit is positive int limit = lair->getSpawnLimit(); EXPECT_TRUE( limit > 0 ) << "Spawn limit in lair template " << templateName << " is not positive"; // Verify any configured buildings exist int buildingCount = 0; for(int i=0; i<=4; i++){ Vector<String>* buildings = lair->getBuildings( i ); if( buildings == NULL ) continue; buildingCount += buildings->size(); for( int j=0; j < buildings->size(); j++ ){ String buildingTemplate = buildings->get(j); std::string buildingStr = buildingTemplate.toCharArray(); SharedObjectTemplate* templateObject = templateManager->getTemplate(buildingTemplate.hashCode()); EXPECT_TRUE( templateObject != NULL && templateObject->isSharedTangibleObjectTemplate() ) << "Building template " << buildingStr << " in lair template " << templateName << " does not exist"; if( lair->getBuildingType() == LairTemplate::LAIR ){ EXPECT_TRUE( buildingTemplate.beginsWith( "object/tangible/lair/") ) << "Building template " << buildingStr << " in lair template " << templateName << " is not a child of object/tangible/lair/"; } if( lair->getBuildingType() == LairTemplate::THEATER ){ EXPECT_TRUE( buildingTemplate.beginsWith( "object/building/poi/") ) << "Building template " << buildingStr << " in lair template " << templateName << " is not a child of object/building/poi/"; } } } // Verify mission buildings exist and are lairs String missionBuilding = lair->getMissionBuilding(10); if (!missionBuilding.isEmpty()) { std::string buildingStr = missionBuilding.toCharArray(); SharedObjectTemplate* templateObject = templateManager->getTemplate(missionBuilding.hashCode()); EXPECT_TRUE( templateObject != NULL && templateObject->isSharedTangibleObjectTemplate() ) << "Mission building template " << buildingStr << " in lair template " << templateName << " does not exist"; EXPECT_TRUE( missionBuilding.beginsWith( "object/tangible/lair/") ) << "Mission building template " << buildingStr << " in lair template " << templateName << " is not a child of object/tangible/lair/"; } if( lair->getBuildingType() == LairTemplate::THEATER ){ EXPECT_TRUE( buildingCount > 0 ) << "There are no buildings configured in theater type lair template " << templateName; } if( lair->getBuildingType() == LairTemplate::NONE ){ EXPECT_TRUE( buildingCount == 0 ) << "There are buildings configured in 'none' type lair template " << templateName; } if( lair->getBuildingType() == LairTemplate::LAIR ){ EXPECT_TRUE( buildingCount > 0 ) << "There are no buildings configured in lair type lair template " << templateName; } } // Test Spawn Groups HashTableIterator<uint32, Reference<SpawnGroup*> > spawnIterator = CreatureTemplateManager::instance()->spawnGroupIterator(); while (spawnIterator.hasNext()) { SpawnGroup* group = spawnIterator.next(); std::string templateName( group->getTemplateName().toCharArray() ); Vector<String> lairTemplates; // Verify spawn list Vector<Reference<LairSpawn*> >* spawnList = group->getSpawnList(); for (int i = 0; i < spawnList->size(); i++) { LairSpawn* spawn = spawnList->get(i); std::string lairName( spawn->getLairTemplateName().toCharArray() ); // Verify lair template exists and isn't duplicated in the group String lairTemplateName = spawn->getLairTemplateName(); Reference<LairTemplate*> lairTemplate = CreatureTemplateManager::instance()->getLairTemplate(lairTemplateName.hashCode()); EXPECT_TRUE( lairTemplate != NULL ) << "Lair template " << lairName << " in spawn group " << templateName << " does not exist."; EXPECT_FALSE( lairTemplates.contains(lairTemplateName) ) << "Lair template " << lairName << " is duplicated in spawn group " << templateName; lairTemplates.add(lairTemplateName); // Verify spawn limit is at least -1 float spawnLimit = spawn->getSpawnLimit(); EXPECT_TRUE( spawnLimit >= -1 ) << "SpawnLimit for lairTemplate " << lairName << " in spawn group " << templateName << " is less than -1."; // Verify difficulties int minDiff = spawn->getMinDifficulty(); int maxDiff = spawn->getMaxDifficulty(); EXPECT_TRUE( minDiff > 0 ) << "MinDifficulty for lairTemplate " << lairName << " in spawn group " << templateName << " is not positive."; EXPECT_TRUE( maxDiff >= minDiff ) << "MaxDifficulty for lairTemplate " << lairName << " in spawn group " << templateName << " is less than min difficulty."; // Verify number to spawn is not negative int numberToSpawn = spawn->getNumberToSpawn(); EXPECT_TRUE( numberToSpawn >= 0 ) << "NumberToSpawn for lairTemplate " << lairName << " in spawn group " << templateName << " is negative."; // Verify weighting is positive int weighting = spawn->getWeighting(); EXPECT_TRUE( weighting > 0 ) << "Weighting for lairTemplate " << lairName << " in spawn group " << templateName << " is not positive."; // Verify size is at least 1 float size = spawn->getSize(); EXPECT_TRUE( size >= 1 ) << "Size for lairTemplate " << lairName << " in spawn group " << templateName << " is less than 1."; } } // Test Destroy Mission Spawn Groups HashTableIterator<uint32, Reference<SpawnGroup*> > missionIterator = CreatureTemplateManager::instance()->destroyMissionGroupIterator(); while (missionIterator.hasNext()) { SpawnGroup* group = missionIterator.next(); std::string templateName( group->getTemplateName().toCharArray() ); Vector<String> lairTemplates; // Verify spawn list Vector<Reference<LairSpawn*> >* spawnList = group->getSpawnList(); for (int i = 0; i < spawnList->size(); i++) { LairSpawn* spawn = spawnList->get(i); std::string lairName( spawn->getLairTemplateName().toCharArray() ); // Verify lair template exists String lairTemplateName = spawn->getLairTemplateName(); Reference<LairTemplate*> lairTemplate = CreatureTemplateManager::instance()->getLairTemplate(lairTemplateName.hashCode()); EXPECT_TRUE( lairTemplate != NULL ) << "Lair template " << lairName << " in destroy mission spawn group " << templateName << " does not exist."; EXPECT_FALSE( lairTemplates.contains(lairTemplateName) ) << "Lair template " << lairName << " is duplicated in destroy mission spawn group " << templateName; lairTemplates.add(lairTemplateName); if (lairTemplate != NULL) { // Verify that lair template has a valid mission building or is of type LAIR String missionBuilding = lairTemplate->getMissionBuilding(10); if (!missionBuilding.isEmpty()) { std::string buildingStr = missionBuilding.toCharArray(); SharedObjectTemplate* templateObject = templateManager->getTemplate(missionBuilding.hashCode()); EXPECT_TRUE( templateObject != NULL && templateObject->isSharedTangibleObjectTemplate() ) << "Mission building template " << buildingStr << " in lair template " << lairName << ", part of destroy mission group " << templateName << " does not exist"; EXPECT_TRUE( missionBuilding.beginsWith( "object/tangible/lair/") ) << "Mission building template " << buildingStr << " in lair template " << lairName << ", part of destroy mission group " << templateName << " is not a child of object/tangible/lair/"; } else { EXPECT_TRUE( lairTemplate->getBuildingType() == LairTemplate::LAIR ) << "Lair template " << lairName << ", part of destroy mission group " << templateName << " is not of type LAIR"; } } // Verify difficulties int minDiff = spawn->getMinDifficulty(); int maxDiff = spawn->getMaxDifficulty(); EXPECT_TRUE( minDiff > 0 ) << "MinDifficulty for lairTemplate " << lairName << " in destroy mission spawn group " << templateName << " is not positive."; EXPECT_TRUE( maxDiff >= minDiff ) << "MaxDifficulty for lairTemplate " << lairName << " in destroy mission spawn group " << templateName << " is less than min difficulty."; // Verify size is at least 1 float size = spawn->getSize(); EXPECT_TRUE( size >= 1 ) << "Size for lairTemplate " << lairName << " in destroy mission spawn group " << templateName << " is less than 1."; } } }
bool PetManagerImplementation::handleCommandTraining(CreatureObject* speaker, AiAgent* pet, const String& message){ if( speaker == NULL || pet == NULL ) return false; if( message.isEmpty() ) return false; ManagedWeakReference< CreatureObject*> linkedCreature = pet->getLinkedCreature(); if( linkedCreature == NULL ) return false; // Only owner may train if( linkedCreature != speaker) return false; ManagedReference<PetControlDevice*> pcd = pet->getControlDevice().get().castTo<PetControlDevice*>(); if( pcd == NULL ) return false; if( pcd->hasTrainedCommandString(message) ){ pet->showFlyText("npc_reaction/flytext","confused", 204, 0, 0); // "?!!?!?!" return true; } unsigned int trainingCommand = pcd->getTrainingCommand(); int petType = pcd->getPetType(); // Train command if (petType == CREATUREPET) { bool alreadyTrained = pcd->hasTrainedCommand(trainingCommand); if (!alreadyTrained) { bool success = false; int skill = speaker->getSkillMod("tame_level"); int roll = System::random(skill + 30); if (skill > roll) success = true; if (!success) { pet->showFlyText("npc_reaction/flytext","confused", 204, 0, 0); // "?!!?!?!" speaker->sendSystemMessage("@pet/pet_menu:pet_nolearn"); // Your pet doesn't seem to understand you. return true; } } // Success pcd->addTrainedCommand( trainingCommand, message ); pet->showFlyText("npc_reaction/flytext","threaten", 204, 0, 0); // "!" speaker->sendSystemMessage("@pet/pet_menu:pet_learn"); // You teach your pet a new command. if (!alreadyTrained) { CreatureTemplate* creatureTemplate = pet->getCreatureTemplate(); if (creatureTemplate == NULL) return true; PlayerManager* playerManager = zoneServer->getPlayerManager(); playerManager->awardExperience(speaker, "creaturehandler", 10 * creatureTemplate->getLevel()); } } else{ pcd->addTrainedCommand( trainingCommand, message ); pet->showFlyText("npc_reaction/flytext","threaten", 204, 0, 0); // "!" speaker->sendSystemMessage("@pet/pet_menu:pet_learn"); // You teach your pet a new command. } // No renaming of faction pets if (petType == FACTIONPET) return true; // Check for naming string StringTokenizer tokenizer(message); tokenizer.setDelimeter(" "); String parsedName = ""; int numberOfSubStrings = 0; while (tokenizer.hasMoreTokens()) { numberOfSubStrings++; if (!parsedName.isEmpty()) break; tokenizer.getStringToken(parsedName); } String futureName = pcd->getFutureName(); unsigned int namingProgress = pcd->getNamingProgress(); // Validate and check name if (numberOfSubStrings > 1) { ZoneProcessServer* zps = pet->getZoneProcessServer(); NameManager* nameManager = zps->getNameManager(); if (nameManager->validateName(parsedName) != NameManagerResult::ACCEPTED) { return true; } if (futureName == parsedName && !pcd->hasUsedNamingCommand(trainingCommand)) { pcd->incrementNamingProgress(trainingCommand); } else { pcd->resetNamingProgress(); pcd->incrementNamingProgress(trainingCommand); pcd->setFutureName(parsedName); return true; } } else { pcd->resetNamingProgress(); parsedName = ""; pcd->setFutureName(parsedName); return true; } // Set name, if applicable if (pcd->getNamingProgress() == 4) { UnicodeString newName = "(" + futureName + ")"; pcd->setCustomObjectName(newName, true); pet->setCustomObjectName(newName, true); pcd->resetNamingProgress(); } return true; }
void DnaManager::generateSample(Creature* creature, CreatureObject* player,int quality){ if (quality < 0 || quality > 7) { return; } Locker lock(creature,player); CreatureTemplate* creatureTemplate = dynamic_cast<CreatureTemplate*>(creature->getCreatureTemplate()); int ferocity = creatureTemplate->getFerocity(); int cl = creature->getLevel(); int cle = instance()->generateScoreFor(DnaManager::CLEVERNESS,cl,quality); int cou = instance()->generateScoreFor(DnaManager::COURAGE,cl,quality); int dep = instance()->generateScoreFor(DnaManager::DEPENDABILITY,cl,quality); int dex = instance()->generateScoreFor(DnaManager::DEXTERITY,cl,quality); int end = instance()->generateScoreFor(DnaManager::ENDURANCE,cl,quality); int fie = instance()->generateScoreFor(DnaManager::FIERCENESS,ferocity,quality); int frt = instance()->generateScoreFor(DnaManager::FORTITUDE,cl,quality); int har = instance()->generateScoreFor(DnaManager::HARDINESS,cl,quality); int ite = instance()->generateScoreFor(DnaManager::INTELLIGENCE,cl,quality); int pow = instance()->generateScoreFor(DnaManager::POWER,cl,quality); // We should now have enough to generate a sample ManagedReference<DnaComponent*> prototype = player->getZoneServer()->createObject(qualityTemplates.get(quality), 1).castTo<DnaComponent*>(); if (prototype == NULL) { return; } Locker clocker(prototype); // Check Here for unique npcs StringId* nameId = creature->getObjectName(); if (nameId->getFile().isEmpty() || nameId->getStringID().isEmpty()) { prototype->setSource(creature->getCreatureName().toString()); } else { prototype->setSource(nameId->getFullPath()); } prototype->setQuality(quality); prototype->setLevel(cl); String serial = player->getZoneServer()->getCraftingManager()->generateSerial(); prototype->setSerialNumber(serial); prototype->setStats(cle,end,fie,pow,ite,cou,dep,dex,frt,har); prototype->setStun(creatureTemplate->getStun()); prototype->setKinetic(creatureTemplate->getKinetic()); prototype->setEnergy(creatureTemplate->getEnergy()); prototype->setBlast(creatureTemplate->getBlast()); prototype->setHeat(creatureTemplate->getHeat()); prototype->setCold(creatureTemplate->getCold()); prototype->setElectric(creatureTemplate->getElectricity()); prototype->setAcid(creatureTemplate->getAcid()); prototype->setSaber(creatureTemplate->getLightSaber()); prototype->setRanged(creatureTemplate->getWeapons().size() > 0); prototype->setArmorRating(creatureTemplate->getArmor()); CreatureAttackMap* attackMap = creatureTemplate->getAttacks(); if (attackMap->size() > 0) { prototype->setSpecialAttackOne(String(attackMap->getCommand(0))); if(attackMap->size() > 1) { prototype->setSpecialAttackTwo(String(attackMap->getCommand(1))); } } ManagedReference<SceneObject*> inventory = player->getSlottedObject("inventory"); if (inventory->hasFullContainerObjects()) { StringIdChatParameter err("survey", "no_inv_space"); player->sendSystemMessage(err); player->setPosture(CreaturePosture::UPRIGHT, true); return; } Locker locker(inventory); inventory->transferObject(prototype, -1, true,false); inventory->broadcastObject(prototype, true); }
bool CreatureImplementation::isVicious() { CreatureTemplate* creatureTemplate = npcTemplate.get(); return creatureTemplate->getPvpBitmask() & CreatureFlag::AGGRESSIVE; }
void PetControlDeviceImplementation::fillAttributeList(AttributeListMessage* alm, CreatureObject* object) { SceneObjectImplementation::fillAttributeList(alm, object); if (petType == PetManager::DROIDPET) { alm->insertAttribute("creature_vitality", String::valueOf(vitality) + "/" + String::valueOf(maxVitality)); ManagedReference<DroidObject*> droid = this->controlledObject.get().castTo<DroidObject*>(); if (droid != NULL) { droid->fillAttributeList(alm, object); } } else { ManagedReference<AiAgent*> pet = cast<AiAgent*>(this->controlledObject.get().get()); if (pet != NULL) { alm->insertAttribute("challenge_level", pet->getLevel()); if (petType == PetManager::CREATUREPET) alm->insertAttribute("creature_vitality", String::valueOf(vitality) + "/" + String::valueOf(maxVitality)); alm->insertAttribute("creature_health", pet->getBaseHAM(0)); alm->insertAttribute("creature_action", pet->getBaseHAM(3)); alm->insertAttribute("creature_mind", pet->getBaseHAM(6)); int armor = pet->getArmor(); if (armor == 0) alm->insertAttribute("armor_rating", "None"); else if (armor == 1) alm->insertAttribute("armor_rating", "Light"); else if (armor == 2) alm->insertAttribute("armor_rating", "Medium"); else if (armor == 3) alm->insertAttribute("armor_rating", "Heavy"); if (pet->getKinetic() < 0) alm->insertAttribute("dna_comp_armor_kinetic", "Vulnerable"); else alm->insertAttribute("dna_comp_armor_kinetic", pet->getKinetic()); if (pet->getEnergy() < 0) alm->insertAttribute("dna_comp_armor_energy", "Vulnerable"); else alm->insertAttribute("dna_comp_armor_energy", pet->getEnergy()); if (pet->getBlast() < 0) alm->insertAttribute("dna_comp_armor_blast", "Vulnerable"); else alm->insertAttribute("dna_comp_armor_blast", pet->getBlast()); if (pet->getHeat() < 0) alm->insertAttribute("dna_comp_armor_heat", "Vulnerable"); else alm->insertAttribute("dna_comp_armor_heat", pet->getHeat()); if (pet->getCold() < 0) alm->insertAttribute("dna_comp_armor_cold", "Vulnerable"); else alm->insertAttribute("dna_comp_armor_cold", pet->getCold()); if (pet->getElectricity() < 0) alm->insertAttribute("dna_comp_armor_electric", "Vulnerable"); else alm->insertAttribute("dna_comp_armor_electric", pet->getElectricity()); if (pet->getAcid() < 0) alm->insertAttribute("dna_comp_armor_acid", "Vulnerable"); else alm->insertAttribute("dna_comp_armor_acid", pet->getAcid()); if (pet->getStun() < 0) alm->insertAttribute("dna_comp_armor_stun", "Vulnerable"); else alm->insertAttribute("dna_comp_armor_stun", pet->getStun()); if (pet->getLightSaber() < 0) alm->insertAttribute("dna_comp_armor_saber", "Vulnerable"); else alm->insertAttribute("dna_comp_armor_saber", pet->getLightSaber()); ManagedReference<WeaponObject*> weapon = pet->getWeapon(); if (weapon != NULL) alm->insertAttribute("creature_attack", weapon->getAttackSpeed()); alm->insertAttribute("creature_tohit", pet->getChanceHit()); alm->insertAttribute("creature_damage", String::valueOf(pet->getDamageMin()) + " - " + String::valueOf(pet->getDamageMax())); if (petType == PetManager::CREATUREPET) { CreatureAttackMap* attMap = pet->getAttackMap(); if (attMap->size() > 0) { String str = StringIdManager::instance()->getStringId(("@combat_effects:" + pet->getAttackMap()->getCommand(0)).hashCode()).toString(); alm->insertAttribute("spec_atk_1", str); } else alm->insertAttribute("spec_atk_1", " ---"); if (attMap->size() > 1) { String str = StringIdManager::instance()->getStringId(("@combat_effects:" + pet->getAttackMap()->getCommand(1)).hashCode()).toString(); alm->insertAttribute("spec_atk_2", str); } else alm->insertAttribute("spec_atk_2", " ---"); CreatureTemplate* creatureTemplate = pet->getCreatureTemplate(); if (creatureTemplate != NULL) { if (creatureTemplate->getWeapons().size() > 0) alm->insertAttribute("dna_comp_ranged_attack", "Yes"); else alm->insertAttribute("dna_comp_ranged_attack", "No"); } else alm->insertAttribute("dna_comp_ranged_attack", "No"); } } } // Trained Commands if ( trainedCommands.size() > 0) { alm->insertAttribute("pet_command", "" ); } if( trainedCommands.contains(PetManager::STAY) ){ alm->insertAttribute("pet_command_1", trainedCommands.get(PetManager::STAY) ); } if( trainedCommands.contains(PetManager::FOLLOW) ){ alm->insertAttribute("pet_command_0", trainedCommands.get(PetManager::FOLLOW) ); } if( trainedCommands.contains(PetManager::STORE) ){ alm->insertAttribute("pet_command_11", trainedCommands.get(PetManager::STORE) ); } if( trainedCommands.contains(PetManager::ATTACK) ){ alm->insertAttribute("pet_command_4", trainedCommands.get(PetManager::ATTACK) ); } if( trainedCommands.contains(PetManager::GUARD) ){ alm->insertAttribute("pet_command_2", trainedCommands.get(PetManager::GUARD) ); } if( trainedCommands.contains(PetManager::FRIEND) ){ alm->insertAttribute("pet_command_3", trainedCommands.get(PetManager::FRIEND) ); } if( trainedCommands.contains(PetManager::FOLLOWOTHER) ){ alm->insertAttribute("pet_command_17", trainedCommands.get(PetManager::FOLLOWOTHER) ); } if( trainedCommands.contains(PetManager::TRICK1) ){ alm->insertAttribute("pet_command_12", trainedCommands.get(PetManager::TRICK1) ); } if( trainedCommands.contains(PetManager::TRICK2) ){ alm->insertAttribute("pet_command_13", trainedCommands.get(PetManager::TRICK2) ); } if( trainedCommands.contains(PetManager::PATROL) ){ alm->insertAttribute("pet_command_5", trainedCommands.get(PetManager::PATROL) ); } if( trainedCommands.contains(PetManager::FORMATION1) ){ alm->insertAttribute("pet_command_8", trainedCommands.get(PetManager::FORMATION1) ); } if( trainedCommands.contains(PetManager::FORMATION2) ){ alm->insertAttribute("pet_command_9", trainedCommands.get(PetManager::FORMATION2) ); } if( trainedCommands.contains(PetManager::SPECIAL_ATTACK1) ){ alm->insertAttribute("pet_command_18", trainedCommands.get(PetManager::SPECIAL_ATTACK1) ); } if( trainedCommands.contains(PetManager::SPECIAL_ATTACK2) ){ alm->insertAttribute("pet_command_19", trainedCommands.get(PetManager::SPECIAL_ATTACK2) ); } if( trainedCommands.contains(PetManager::RANGED_ATTACK) ){ alm->insertAttribute("pet_command_20", trainedCommands.get(PetManager::RANGED_ATTACK) ); } if( trainedCommands.contains(PetManager::GROUP) ){ alm->insertAttribute("pet_command_16", trainedCommands.get(PetManager::GROUP) ); } if( trainedCommands.contains(PetManager::RECHARGEOTHER) ){ alm->insertAttribute("@pet/pet_menu:menu_recharge_other", trainedCommands.get(PetManager::RECHARGEOTHER) ); } if( trainedCommands.contains(PetManager::TRANSFER) ){ alm->insertAttribute("pet_command_10", trainedCommands.get(PetManager::TRANSFER) ); } }