void PetControlDeviceImplementation::spawnObject(CreatureObject* player) {
	ZoneServer* zoneServer = getZoneServer();

	ManagedReference<TangibleObject*> controlledObject = this->controlledObject.get();

	if (controlledObject == NULL)
		return;

	assert(controlledObject->isLockedByCurrentThread());

	if (!isASubChildOf(player))
		return;

	ManagedReference<TradeSession*> tradeContainer = player->getActiveSession(SessionFacadeType::TRADE).castTo<TradeSession*>();

	if (tradeContainer != NULL) {
		server->getZoneServer()->getPlayerManager()->handleAbortTradeMessage(player);
	}

	controlledObject->initializePosition(player->getPositionX(), player->getPositionZ(), player->getPositionY());
	ManagedReference<CreatureObject*> creature = NULL;

	if (controlledObject->isCreatureObject()) {
		creature = cast<CreatureObject*>(controlledObject.get());
		creature->setCreatureLink(player);
		creature->setControlDevice(_this.getReferenceUnsafeStaticCast());
		creature->setFaction(player->getFaction());
		creature->setObjectMenuComponent("PetMenuComponent");

		if (player->getPvpStatusBitmask() & CreatureFlag::PLAYER)
			creature->setPvpStatusBitmask(player->getPvpStatusBitmask() - CreatureFlag::PLAYER, true);
		else
			creature->setPvpStatusBitmask(player->getPvpStatusBitmask(), true);

		if (trainedAsMount && (creature->getOptionsBitmask() ^ 0x1000)) {
			creature->setOptionBit(0x1000);
		}
	}

	Zone* zone = player->getZone();

	if (zone == NULL)
		return;

	ManagedReference<CellObject*> parent = player->getParent().get().castTo<CellObject*>();

	if (parent != NULL)
		parent->transferObject(controlledObject, -1, true);
	else
		zone->transferObject(controlledObject, -1, true);

	updateStatus(1);

	if (petControlObserver != NULL)
		player->dropObserver(ObserverEventType::STARTCOMBAT, petControlObserver);

	AiAgent* pet = cast<AiAgent*>(creature.get());

	if (pet == NULL)
		return;

	ManagedReference<PlayerObject*> ghost = player->getPlayerObject();
	ghost->addToActivePets(pet);

	bool isDroid = false;
	if (pet->isDroidObject()) {
		DroidObject* droid = cast<DroidObject*>(pet);
		isDroid = true;
		if( droid == NULL )
			return;

		// Sanity check that there aren't outstanding power/skill mod tasks
		droid->removePendingTask( "droid_power" );
		droid->removePendingTask( "droid_skill_mod" );
		droid->initDroidModules();
		droid->onCall();
		droid->loadSkillMods(player);
		// Submit new power task
		Reference<Task*> droidPowerTask = new DroidPowerTask( droid );
		droid->addPendingTask("droid_power", droidPowerTask, 120000); // 2 min
		// Submit new skill mod task
		Reference<Task*> droidSkillModTask = new DroidSkillModTask( droid, player );
		droid->addPendingTask("droid_skill_mod", droidSkillModTask, 3000); // 3 sec
	}

	pet->setHomeLocation(player->getPositionX(), player->getPositionZ(), player->getPositionY(), parent);
	pet->setNextStepPosition(player->getPositionX(), player->getPositionZ(), player->getPositionY(), parent);
	pet->clearPatrolPoints();
	if (petType == PetManager::CREATUREPET) {
		pet->setCreatureBitmask(CreatureFlag::PET);
	}
	if (petType == PetManager::DROIDPET) {
		pet->setCreatureBitmask(CreatureFlag::DROID_PET);
	}
	if (petType == PetManager::FACTIONPET) {
		pet->setCreatureBitmask(CreatureFlag::FACTION_PET);
		/** dont know if npc faction pets trained via converse instead of radial
		if (pet->isNonPlayerCreatureObject() && pet->getDiet() != CreatureFlag::NONE) // show converse to npcs that eat food i.e. not atst
			pet->setOptionBit(OptionBitmask::CONVERSE,true);
		**/
	}
	pet->activateLoad("");
	pet->activateRecovery();
	// Not training any commands
	trainingCommand = 0;
	clearPatrolPoints();
}
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);
}
Пример #3
0
void SpawnAreaMap::loadStaticSpawns() {
	String planetName = zone->getZoneName();

	LuaObject obj = lua->getGlobalObject(planetName + "_static_spawns");

	if (!obj.isValidTable()) {
		obj.pop();
		return;
	}

	int count = 0;
	int max = obj.getTableSize();

	for (int i = 1; i <= obj.getTableSize(); ++i) {
		lua_rawgeti(obj.getLuaState(), -1, i);
		LuaObject spawn(obj.getLuaState());

		if (spawn.isValidTable()) {
			CreatureManager* creatureManager = zone->getCreatureManager();

			String name = obj.getStringAt(1);
			uint32 respawn = obj.getIntAt(2);
			float x = obj.getFloatAt(3);
			float z = obj.getFloatAt(4);
			float y = obj.getFloatAt(5);
			float heading = obj.getFloatAt(6);
			uint64 parentID = obj.getLongAt(7);
			String moodString;
			UnicodeString customName;
			String aiString;
			int junkDealerBuyingType =0;
			int junkDealerConversationType =0;
			if (obj.getTableSize() > 7)
				moodString = obj.getStringAt(8);

			if (obj.getTableSize() > 8)
				customName = obj.getStringAt(9);

			if (obj.getTableSize() > 9)
				aiString = obj.getStringAt(10);

			if (obj.getTableSize() > 10)
				junkDealerBuyingType = obj.getIntAt(11);

			if (obj.getTableSize() > 11)
				junkDealerConversationType = obj.getIntAt(12);

			if (parentID == 0)
				z = zone->getHeight(x, y);

			ManagedReference<CreatureObject*> creatureObject = creatureManager->spawnCreature(name.hashCode(), 0, x, z, y, parentID);

			if (creatureObject != NULL) {
				Locker objLocker(creatureObject);

				creatureObject->setDirection(Math::deg2rad(heading));
				
				if (creatureObject->isJunkDealer()){
					cast<JunkdealerCreature*>(creatureObject.get())->setJunkDealerConversationType(junkDealerConversationType);
					cast<JunkdealerCreature*>(creatureObject.get())->setJunkDealerBuyerType(junkDealerBuyingType);
				}
				if (!moodString.isEmpty()) {
					creatureObject->setMoodString(moodString);

					//TODO: remove after fixing commoners
					if (moodString == "conversation" || moodString == "calm") {
						creatureObject->setPvpStatusBitmask(0);
						creatureObject->setCloseObjects(NULL);
					}
				}

				if (!customName.isEmpty())
					creatureObject->setCustomObjectName(customName, true);

				if (creatureObject->isAiAgent()) {
					AiAgent* ai = cast<AiAgent*>( creatureObject.get());
					ai->setRespawnTimer(respawn);
					if (!aiString.isEmpty()) {
						ai->activateLoad(aiString);
					}
				}

				if (name.contains("trainer_")) {
					Vector3 coords(creatureObject.get()->getWorldPositionX(), creatureObject.get()->getWorldPositionY(), 0);
					trainerObjects.add(coords);
				}
			} else {
				StringBuffer msg;
				msg << "could not spawn mobile: " + name;
				error(msg.toString());
			}
		}

		spawn.pop();

		if (ConfigManager::instance()->isProgressMonitorActivated())
			printf("\r\tLoading static spawns: [%d] / [%d]\t", ++count, max);
	}

	obj.pop();


	//--{"mobile", x, z, y, degrees heading, parentID}



	//spawnCreature(uint32 templateCRC, uint32 objectCRC, float x, float z, float y, uint64 parentID)
}