Example #1
0
NPCObject* PersistentNpcFactory::_createPersistentNpc(DatabaseResult* result)
{
    NPCObject*		npc	;
    NpcIdentifier	npcIdentifier;


    uint64 count = result->getRowCount();

    result->GetNextRow(mNpcIdentifierBinding,(void*)&npcIdentifier);
    result->ResetRowIndex();

    switch(npcIdentifier.mFamilyId)
    {
    case NpcFamily_Trainer:
        npc	= new Trainer();
        break;
    case NpcFamily_Filler:
        npc	= new FillerNPC();
        break;
    case NpcFamily_QuestGiver:
        npc	= new QuestGiver();
        break;

    default:
    {
        npc = new NPCObject();
        gLogger->log(LogManager::DEBUG,"PersistentNpcFactory::createPersistent unknown Family %u",npcIdentifier.mFamilyId);
    }
    break;
    }

    Inventory*		npcInventory	= new Inventory();
    npcInventory->setParent(npc);

    result->GetNextRow(mPersistentNpcBinding,(void*)npc);

    npc->mHam.mHealth.setCurrentHitPoints(500);
    npc->mHam.mAction.setCurrentHitPoints(500);
    npc->mHam.mMind.setCurrentHitPoints(500);
    npc->mHam.calcAllModifiedHitPoints();

    // inventory
    npcInventory->setId(npc->mId + INVENTORY_OFFSET);
    npcInventory->setParentId(npc->mId);
    npcInventory->setModelString("object/tangible/inventory/shared_creature_inventory.iff");
    npcInventory->setName("inventory");
    npcInventory->setNameFile("item_n");
    npcInventory->setTangibleGroup(TanGroup_Inventory);
    npcInventory->setTangibleType(TanType_CreatureInventory);
    npc->mEquipManager.addEquippedObject(CreatureEquipSlot_Inventory,npcInventory);
    npc->mTypeOptions = 0x108;
    //npc->setPvPStatus(npc->getPvPStatus() + CreaturePvPStatus_Attackable + CreaturePvPStatus_Aggressive);

    npc->setLoadState(LoadState_Attributes);

    // Save default direction, since player can make the npc change heading.
    npc->storeDefaultDirection();

    return npc;
}
Example #2
0
bool Tutorial::isLowHam(uint64 npcId, int32 hamLevel)
{
    NPCObject* npc = dynamic_cast<NPCObject*>(gWorldManager->getObjectById(npcId));
    if (npc)
    {
        if ((npc->getHam()->getPropertyValue(HamBar_Health,HamProperty_CurrentHitpoints) < hamLevel) ||
                (npc->getHam()->getPropertyValue(HamBar_Action,HamProperty_CurrentHitpoints) < hamLevel) ||
                (npc->getHam()->getPropertyValue(HamBar_Mind,HamProperty_CurrentHitpoints) < hamLevel) ||
                (mPlayerObject->getHam()->getPropertyValue(HamBar_Health,HamProperty_CurrentHitpoints) < hamLevel) ||
                (mPlayerObject->getHam()->getPropertyValue(HamBar_Action,HamProperty_CurrentHitpoints) < hamLevel) ||
                (mPlayerObject->getHam()->getPropertyValue(HamBar_Mind,HamProperty_CurrentHitpoints) < hamLevel))
        {
            return true;
        }
    }
    return false;
}
Example #3
0
void Food::prepareCustomRadialMenu(CreatureObject* creatureObject, uint8 itemCount)
{
    RadialMenu* radial	= new RadialMenu();

    CreatureObject* unknownCreature;
    Inventory* creatureInventory;
    if (this->getParentId() &&
            (unknownCreature = dynamic_cast<CreatureObject*>(gWorldManager->getObjectById(this->getParentId() - 1))) &&
            (creatureInventory = dynamic_cast<Inventory*>(unknownCreature->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory))) &&
            (creatureInventory->getId() == this->getParentId()))
    {
        // Its an object in an inventory

        NPCObject* npcObject = dynamic_cast<NPCObject*>(unknownCreature);
        if (npcObject)
        {
            if ((npcObject->getNpcFamily() == NpcFamily_AttackableCreatures) && npcObject->isDead())
            {
                // I'm pretty sure we are a loot item.
                radial->addItem(1,0,radId_itemPickup,radAction_ObjCallback,"@ui_radial:loot");
                radial->addItem(2,0,radId_examine,radAction_Default);
                mRadialMenu = RadialMenuPtr(radial);
                return;
            }
        }
    }

    // Note: If we are to never use the default "Eat", THEN remove the isTutorial()-condition test.
    if (gWorldConfig->isTutorial())
    {
        // Tutorial clearly states that we shall use the "Use"-option.
        radial->addItem(1,0,radId_itemUse,radAction_ObjCallback,"Use");
    }
    else
    {
        radial->addItem(1,0,radId_itemUse,radAction_ObjCallback,"");		// Default.
    }
    radial->addItem(2,0,radId_examine,radAction_ObjCallback,"");
    radial->addItem(3,0,radId_itemDestroy,radAction_ObjCallback,"");
    mRadialMenu = RadialMenuPtr(radial);


}
Example #4
0
void PersistentNpcFactory::handleDatabaseJobComplete(void* ref,DatabaseResult* result)
{
    QueryContainerBase* asyncContainer = reinterpret_cast<QueryContainerBase*>(ref);

    switch(asyncContainer->mQueryType)
    {
    case PersistentNpcQuery_MainData:
    {
        NPCObject* npc = _createPersistentNpc(result);

        if(npc->getLoadState() == LoadState_Loaded && asyncContainer->mOfCallback)
            asyncContainer->mOfCallback->handleObjectReady(npc,asyncContainer->mClient);

        else if(npc->getLoadState() == LoadState_Attributes)
        {
            QueryContainerBase* asContainer = new(mQueryContainerPool.ordered_malloc()) QueryContainerBase(asyncContainer->mOfCallback,PersistentNpcQuery_Attributes,asyncContainer->mClient);
            asContainer->mObject = npc;

            mDatabase->ExecuteSqlAsync(this,asContainer,"SELECT attributes.name,persistent_npc_attributes.value,attributes.internal"
                                       " FROM persistent_npc_attributes"
                                       " INNER JOIN attributes ON (persistent_npc_attributes.attribute_id = attributes.id)"
                                       " WHERE persistent_npc_attributes.npc_id = %"PRIu64" ORDER BY persistent_npc_attributes.order",npc->getId());
		}
    }
    break;

    case PersistentNpcQuery_Attributes:
    {
        _buildAttributeMap(asyncContainer->mObject,result);

        if(asyncContainer->mObject->getLoadState() == LoadState_Loaded && asyncContainer->mOfCallback)
            asyncContainer->mOfCallback->handleObjectReady(asyncContainer->mObject,asyncContainer->mClient);
    }
    break;

    default:
        break;
    }

    mQueryContainerPool.free(asyncContainer);
}
Example #5
0
uint8 CombatManager::_executeAttack(CreatureObject* attacker,CreatureObject* defender,ObjectControllerCmdProperties *cmdProperties,Weapon* weapon)
{
	uint8	randomHitPool			= 100;
	//uint8	randomPoolHitChance		= 100;
	uint8	stateApplied			= 0;
	int32	multipliedDamage		= 0;
	BString	combatSpam				= "melee";

	// first see if we actually hit our target
	uint8 attackResult = _hitCheck(attacker,defender,cmdProperties,weapon);

	// only proceed, if so
	if(!attackResult)
	{
		// TODO: retrieve from weapon
		int32 baseMinDamage	= 50;
		int32 baseMaxDamage	= 100;

		// NOTE: Some weapon data just for tesing and to give the npc a fair chance...

		if (weapon->hasAttribute("cat_wpn_damage.wpn_damage_min"))
		{
			baseMinDamage = weapon->getAttribute<int32>("cat_wpn_damage.wpn_damage_min");
		}
		if (weapon->hasAttribute("cat_wpn_damage.wpn_damage_max"))
		{
			baseMaxDamage = weapon->getAttribute<int32>("cat_wpn_damage.wpn_damage_max");
		}


		//Sanity checks of db data
		if (baseMinDamage < 1)
			baseMinDamage = 1;

		if (baseMaxDamage < 1)
			baseMaxDamage = 1;

		if(baseMaxDamage <= baseMinDamage)
		{
			baseMaxDamage = baseMinDamage +1;
		}

		int32 baseDamage	= -((gRandom->getRand()%(baseMaxDamage - baseMinDamage)) + baseMinDamage);

		// apply damage multiplier
		if(cmdProperties->mDamageMultiplier)
		{
			multipliedDamage = static_cast<uint32>(static_cast<float>(baseDamage) * cmdProperties->mDamageMultiplier);
		}
		else
		{
			multipliedDamage = baseDamage;
		}

		// mitigation
		multipliedDamage = _mitigateDamage(attacker,defender,cmdProperties,multipliedDamage,weapon);

		// state effects
		stateApplied = _tryStateEffects(attacker,defender,cmdProperties,weapon);


		// Here is the deal. When a player makes damage to a npc, we have to register the player, its group, damage done and what (kind of) weapon used.
		NPCObject* npc = dynamic_cast<NPCObject*>(defender);
		if (!defender->isDead() && npc)
		{
			PlayerObject* player = dynamic_cast<PlayerObject*>(attacker);
			if (player)
			{
                npc->updateDamage(player->getId(), player->getGroupId(), weapon->getGroup(), -multipliedDamage, player->GetPosture(), glm::distance(defender->mPosition, player->mPosition));
			}
		}

		// ham damage
		// if no target pool set, pick a random one
		if(!cmdProperties->mHealthHitChance && !cmdProperties->mActionHitChance && !cmdProperties->mMindHitChance)
		{
			switch(gRandom->getRand()%3)
			{
				case 0: randomHitPool = HamBar_Health;	break;
				case 1: randomHitPool = HamBar_Action;	break;
				case 2: randomHitPool = HamBar_Mind;	break;

				default: randomHitPool = 0;				break;
			}
		}

		auto ham = gWorldManager->getKernel()->GetServiceManager()->GetService<swganh::ham::HamService>("HamService");

		//this is pure idiocy in my eyes. Why for gods sake should an object be a creature ?
		// is there precedent through SOE???????????
		if (defender->getCreoGroup() != CreoGroup_AttackableObject)
		{
			// random pool attack
			if(randomHitPool != 100)
			{
				ham->UpdateCurrentHitpoints(defender,randomHitPool,multipliedDamage);
				//defender->getHam()->updatePropertyValue(randomHitPool,HamProperty_CurrentHitpoints,multipliedDamage,true);
			}
			// direct pool attack
			else
			{
				// health hit
				if(cmdProperties->mHealthHitChance)
				{
					ham->UpdateCurrentHitpoints(defender,HamBar_Health,multipliedDamage);
					//defender->getHam()->updatePropertyValue(HamBar_Health,HamProperty_CurrentHitpoints,multipliedDamage,true);
				}
				// action hit
				else if(cmdProperties->mActionHitChance)
				{
					ham->UpdateCurrentHitpoints(defender,HamBar_Action,multipliedDamage);
					//defender->getHam()->updatePropertyValue(HamBar_Action,HamProperty_CurrentHitpoints,multipliedDamage,true);
				}
				// mind hit
				else if(cmdProperties->mMindHitChance)
				{
					ham->UpdateCurrentHitpoints(defender,HamBar_Mind,multipliedDamage);
					//defender->getHam()->updatePropertyValue(HamBar_Mind,HamProperty_CurrentHitpoints,multipliedDamage,true);
				}
			}
		}
		else
		{
			ham->UpdateCurrentHitpoints(defender,HamBar_Health,multipliedDamage);
			//defender->getHam()->updateSingleHam(multipliedDamage, true);
		}
		if (defender->isIncapacitated())
		{
			PlayerObject* playerAttacker = dynamic_cast<PlayerObject*>(attacker);
			if (playerAttacker && playerAttacker->isConnected())
			{
                gMessageLib->SendSystemMessage(::common::OutOfBand("base_player", "prose_target_incap", 0, defender->getId(), 0), playerAttacker);
            }
        }
        if (defender->isDead())
        {
            PlayerObject* playerAttacker = dynamic_cast<PlayerObject*>(attacker);
            if (playerAttacker && playerAttacker->isConnected())
            {
                gMessageLib->SendSystemMessage(::common::OutOfBand("base_player", "killer_target_dead"), playerAttacker, true);
            }
        }
    }


    // fly text and animations
    // default attack(s)
    if(cmdProperties->mCmdCrc == 0xa8fef90a)
    {
        uint32 animCrc = getDefaultAttackAnimation(weapon->getGroup());

        switch(attackResult)
        {
            // hit
        case 0:
        case 2:
        case 3:
        case 4:
        {
            gMessageLib->sendCombatAction(attacker,defender,animCrc,0,0,1);
        }
        break;

        // miss
        case 1:
        {
            gMessageLib->sendCombatAction(attacker,defender,animCrc);
        }
        break;
        }
    }
    // special attack
    else
    {
        switch(attackResult)
        {
            // hit
        case 0:
        case 2:
        case 3:
        case 4:
        {
            gMessageLib->sendCombatAction(attacker,defender,cmdProperties->mAnimationCrc,cmdProperties->mTrail1,cmdProperties->mTrail2,1);
        }
        break;

        //miss
        case 1:
        {
            gMessageLib->sendCombatAction(attacker,defender,cmdProperties->mAnimationCrc,cmdProperties->mTrail1,cmdProperties->mTrail2);
        }
        break;
        }
    }

    switch(attackResult)
    {
    case 0:
    {
        // Defender got hit.
    }
    break;

    case 1:
    {
        gMessageLib->sendFlyText(defender,"combat_effects","miss",255,255,255);
    }
    break;

    case 2:
        // We cant block yet, can we?
    {
        gMessageLib->sendFlyText(defender,"combat_effects","block",0,255,0);
        gMessageLib->sendCombatAction(defender,attacker,0xe430ff04);
    }
    break;

    case 3:
    {
        gMessageLib->sendFlyText(defender,"combat_effects","dodge",0,255,0);
        gMessageLib->sendCombatAction(defender,attacker,0xe430ff04);	// Dodge
    }
    break;

    case 4:
    {
        gMessageLib->sendFlyText(defender,"combat_effects","counterattack",0,255,0);	// I can's see this effect working?
    }
    break;
    }

    // send combat spam
    // default attack
    if(cmdProperties->mCmdCrc == 0xa8fef90a)
    {
        combatSpam = getDefaultSpam(weapon->getGroup());
    }
    // special attack
    else
    {
        if(cmdProperties->mCbtSpam.getLength())
        {
            combatSpam = cmdProperties->mCbtSpam.getAnsi();
        }
    }

    switch(attackResult)
    {
    case 0:
        combatSpam << "_hit";
        break;
    case 1:
        combatSpam << "_miss";
        break;
    case 2:
        combatSpam << "_block";
        break;
    case 3:
        combatSpam << "_evade";
        break;
    case 4:
        combatSpam << "_counter";
        break;

    default:
        break;
    }
    gMessageLib->sendCombatSpam(attacker,defender,-multipliedDamage,"cbt_spam",combatSpam);


    return(0);
}
void ScriptSupport::npcSpawnGeneral(uint64 npcId, uint64 npcPrivateOwnerId, uint64 cellForSpawn, std::string firstname, std::string lastname, float dirY, float dirW, float posX, float posY, float posZ, uint64 respawnDelay) // , uint64 templateId)
{
    glm::quat direction;
    glm::vec3 position;

    direction.x = 0.0;
    direction.y = dirY;
    direction.z = 0.0;
    direction.w = dirW;

    position.x = posX;
    position.y = posY;
    position.z = posZ;

    NPCObject* npc = dynamic_cast<NPCObject*>(gWorldManager->getObjectById(npcId));
    assert(npc);
    if (!npc)
    {
        // Fallback for running in release mode.
        LOG(WARNING) << "ScriptSupport::npcSpawnGeneral: Failed to access NPC id " << npcId;
        return;
    }

    // npc->setId(npcId);
    npc->setParentId(cellForSpawn);	// The cell we will spawn in.
    npc->setCellIdForSpawn(cellForSpawn);



    // THESE TWO ARE NOT GENERALLY FIXED YET.
    npc->setFirstName((int8*)firstname.c_str());
    npc->setLastName((int8*)lastname.c_str());

    // THIS ONE IS NOT GENERALLY FIXED YET.
    // If used for re-spawning npc's, add this id as an internal attribute.
    npc->setPrivateOwner(npcPrivateOwnerId);


    npc->mPosition = position;
    npc->setSpawnPosition(position);

    npc->mDirection = direction;
    npc->setSpawnDirection(direction);
    npc->setRespawnDelay(respawnDelay);

    // Register object with WorldManager.
    // gWorldManager->addObject(npc, true);

    // Update the world about my presence.
    /*
    if (npc->getParentId())
    {
    	// insert into cell
    	npc->setSubZoneId(0);

    	if (CellObject* cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(npc->getParentId())))
    	{
    		cell->addChild(npc);
    	}
    	else
    	{
    	}
    }
    else
    {
    	if (QTRegion* region = gWorldManager->getSI()->getQTRegion(npc->mPosition.x,npc->mPosition.z))
    	{
    		npc->setSubZoneId((uint32)region->getId());
    		region->mTree->addObject(npc);
    	}
    }
    */

    //Inventory* inventory = dynamic_cast<Inventory*>(npc->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory));

    // Register the NPC with the NPC AI-manager.
    if (npc->getTemplateId() == 0)
    {
        // Just to make sure we do not have any old scripts running.
        assert(false);
    }
    npc->respawn();

    // Now we can remove this object from our internal list. WorldManager will handle the destruction.
    // Except for the npc's used in tutorial, they are spawned-despawned with the player.
    if (!gWorldConfig->isTutorial())
    {
        this->eraseObject(npcId);
    }
    /*
    	// The dynamic spawned private owned npc MUST register with their owner.
    	// It's not always the case that the player have had time to track this newly spawned objects,

    	// Private owned objects are invisible to most players and using getKnownPlayers()->empty() to try and save the
    	// sendDataTransformWithParent
    	// and
    	// sendUpdateTransformMessageWithParent
    	// from being called is just ridicules, it's not like we going to spwan a npc from script every second or so.

    	// So please stop messing with this code!!!

    	// Add us to the world.
    	gMessageLib->broadcastContainmentMessage(npc->getId(),npc->getParentId(),-1,npc);

    	// send out position updates to known players
    	npc->setInMoveCount(npc->getInMoveCount() + 1);
    	if (gWorldConfig->isTutorial())
    	{
    		// We need to get the player object that is the owner of this npc.
    		if (npcPrivateOwnerId != 0)
    		{
    			PlayerObject* playerObject = dynamic_cast<PlayerObject*>(gWorldManager->getObjectById(npcPrivateOwnerId));
    			if (playerObject)
    			{

    				if (npc->getParentId())
    				{
    					// We are inside a cell.
    					gMessageLib->sendDataTransformWithParent(npc, playerObject);
    					gMessageLib->sendUpdateTransformMessageWithParent(npc, playerObject);
    				}
    				else
    				{
    					gMessageLib->sendDataTransform(npc, playerObject);
    					gMessageLib->sendUpdateTransformMessage(npc, playerObject);
    				}
    				return;
    			}
    		}
    	}
    	else
    	{
    		if (npc->getParentId())
    		{
    			// We are inside a cell.
    			gMessageLib->sendDataTransformWithParent(npc);
    			gMessageLib->sendUpdateTransformMessageWithParent(npc);
    		}
    		else
    		{
    			gMessageLib->sendDataTransform(npc);
    			gMessageLib->sendUpdateTransformMessage(npc);
    		}
    	}
    	*/
}
Example #7
0
MissionObject* MissionManager::generateCraftingMission(MissionObject* mission)
{
	mission->setMissionType(crafting);

	//TEMP!
	string targets[8][2] =
	{
		{"@item_n:output_governor","object/tangible/mission/quest_item/shared_attunement_grid.iff"},
		{"@item_n:current_alternator","object/tangible/mission/quest_item/shared_current_alternator.iff"},
		{"@item_n:nym_hard_drive","object/tangible/loot/quest/shared_nym_hard_drive.iff"},
		{"@item_n:hyperdrive_part_s01","object/tangible/loot/misc/shared_hyperdrive_part_s01.iff"},
		{"@item_n:dermal_analyzer","object/tangible/loot/npc_loot/shared_dermal_analyzer_generic.iff"},
		{"@item_n:feedback_controller","object/tangible/mission/quest_item/shared_feedback_controller.iff"},
		{"@item_n:power_regulator","object/tangible/mission/quest_item/shared_power_regulator.iff"},
		{"@item_n:attunement_grid","object/tangible/mission/quest_item/shared_attunement_grid.iff"}
	};

	int target_num = gRandom->getRand() % 8;

	//END TEMP

	//Randomly choose a crafting mission
	int mission_num = (gRandom->getRand() % 50)+1;
	mission->setNum(mission_num);

	//Creator
	mission->setCreator(creators[gRandom->getRand() % 9]);

	//Title
	sprintf(mt,"m%dt",mission_num);
	mission->setTitleFile("mission/mission_npc_crafting_neutral_easy");
	mission->setTitle(mt);

	//Details
	sprintf(md,"m%dd",mission_num);
	mission->setDetailFile("mission/mission_npc_crafting_neutral_easy");
	mission->setDetail(md);

    //END TEMP

	ObjectSet inRangeNPCs;
	gWorldManager->getSI()->getObjectsInRange(mission->getOwner(),&inRangeNPCs,ObjType_NPC,1500);

	uint32 cntLoop = 0;
	//Start & End
	bool found = false;
	Location mission_start;
    Location mission_dest;
	ObjectSet::iterator it = inRangeNPCs.begin();
	while(!found && !inRangeNPCs.empty())
	{
		cntLoop++;
		++it;

		if(it == inRangeNPCs.end())
			it = inRangeNPCs.begin();

		NPCObject* npc = dynamic_cast<NPCObject*>(*it);
		if(npc->getNpcFamily() == NpcFamily_Filler)
		{
			uint32 roll		= (gRandom->getRand() / (RAND_MAX  + 1ul) * (9 - 1) + 1);
			if((roll = 5)||(cntLoop > inRangeNPCs.size()))
			{
				if(mission_dest.Coordinates.x == 0)
				{
					mission->setDestinationNPC(npc);
					mission_dest.Coordinates = npc->mPosition;
					mission_dest.CellID = 0;
					mission_dest.PlanetCRC = BString(gWorldManager->getPlanetNameThis()).getCrc();
					mission->setDestination(mission_dest);
				}
				else if(mission_start.Coordinates.x == 0 && mission->getDestinationNPC() != npc)
				{
					mission->setStartNPC(npc);
					mission_start.Coordinates = npc->mPosition;
					mission_start.CellID = 0;
					mission_start.PlanetCRC = BString(gWorldManager->getPlanetNameThis()).getCrc();
					mission->setStart(mission_start);
				}
				else
				{
					found = true;
				}
			}
		}
	}

   //Difficulty
	mission->setDifficulty((gRandom->getRand() % 41) + 40); //value from 30 - 80

	//Reward
	mission->setReward(mission->getDifficulty() * ((gRandom->getRand() % 14) + 15)); //Difficulty * rand: 15-28

	//Target
	mission->setTarget((targets[target_num][0]).getRawData()); //will need to be located from the db

	//Mission Target
	mission->setTargetModel((targets[target_num][1]).getCrc()); //crc = object/tangible/mission/quest_item/shared_attunement_grid.iff

return mission;
}
Example #8
0
MissionObject* MissionManager::generateEntertainerMission(MissionObject* mission,int count)
{

	count < 5 ?
		mission->setMissionType(musician):
	    mission->setMissionType(dancer);

	//Randomly choose an entertainer mission
	int mission_num = (gRandom->getRand() % 50)+1;
	mission->setNum(mission_num);

	ObjectSet inRangeNPCs;
	gWorldManager->getSI()->getObjectsInRange(mission->getOwner(),&inRangeNPCs,ObjType_NPC,3000);
	//Start
	uint32 cntLoop = 0;
	bool found = false;
	Location mission_dest;
	ObjectSet::iterator it = inRangeNPCs.begin();
	while(!found && !inRangeNPCs.empty())
	{
		cntLoop++;
		++it;
		if(it == inRangeNPCs.end())
			it = inRangeNPCs.begin();

		NPCObject* npc = dynamic_cast<NPCObject*>(*it);
		if(npc->getNpcFamily() == NpcFamily_Filler)
		{
			uint32 roll		= (gRandom->getRand() / (RAND_MAX  + 1ul) * (9 - 1) + 1);
			if((roll = 5)||(cntLoop > inRangeNPCs.size()))
			{
				if(mission_dest.Coordinates.x == 0 && mission->getDestinationNPC() != npc)
				{
					mission->setStartNPC(npc);
					mission_dest.Coordinates = npc->mPosition;
					mission_dest.CellID = 0;
					mission_dest.PlanetCRC = BString(gWorldManager->getPlanetNameThis()).getCrc();
					mission->setDestination(mission_dest);
					mission->setDestinationNPC(npc);
					found = true;
				}
			}
		}
	}

	//Creator
	mission->setCreator(creators[gRandom->getRand() % 9]);

    //Mission Title
	sprintf(mt,"m%dt",mission_num);

	count < 5 ?
		mission->setTitleFile("mission/mission_npc_musician_neutral_easy") :
		mission->setTitleFile("mission/mission_npc_dancer_neutral_easy");
	mission->setTitle(mt);

	//Mission Description
	sprintf(md,"m%do",mission_num);

	count < 5 ?
		mission->setDetailFile("mission/mission_npc_musician_neutral_easy") :
		mission->setDetailFile("mission/mission_npc_dancer_neutral_easy");
	mission->setDetail(md);

   //Diffaculty
	mission->setDifficulty((gRandom->getRand() % 90)+3);

	//Payment
	mission->setReward((gRandom->getRand() % 2500)+500);

	//Target Name
	mission->setTarget("Entertainer");

	//Mission Target
	mission->setTargetModel(0x491099A6); //crc = object/tangible/instrument/shared_organ_max_rebo.iff

return mission;
}
Example #9
0
MissionObject* MissionManager::generateDeliverMission(MissionObject* mission)
{
	mission->setMissionType(deliver);

	//TEMP

	missionData mission_deliver_hard[2] =
	{
		{"mission/mission_deliver_neutral_hard",25},
		{"mission/mission_deliver_neutral_hard_non_persistent_from_npc",15},
	};

	//Randomly choose a stf file
	int stf_file = gRandom->getRand() % 2;

	//Randomly choose a mission in that file
	int mission_num = (gRandom->getRand() % mission_deliver_hard[stf_file].num)+1;
	mission->setNum(mission_num);

    //END TEMP

	ObjectSet inRangeNPCs;
	gWorldManager->getSI()->getObjectsInRange(mission->getOwner(),&inRangeNPCs,ObjType_NPC,1500);

	//Start & End
	bool found = false;
	Location mission_start;
    Location mission_dest;
	ObjectSet::iterator it = inRangeNPCs.begin();

	//we may stall the main thread with the way it was done ???? however often enough the mission generation never finished!!!!!!!!!!!!!!!


	//get a list containing all suitable npcs and generate a random number corresponding to one of the npcs

	if(inRangeNPCs.size() < 2)
		return NULL;


	uint32 count = 0;

	while(!found && !inRangeNPCs.empty())
	{
		count ++;
		++it;
		if(it == inRangeNPCs.end())
			it = inRangeNPCs.begin();

		NPCObject* npc = dynamic_cast<NPCObject*>(*it);
		if(npc->getNpcFamily() == NpcFamily_Filler)
		{
			uint32 roll		= (gRandom->getRand() / (RAND_MAX  + 1ul) * (9 - 1) + 1);
			if((roll = 5)||(count > inRangeNPCs.size()))
			{
				if(mission_dest.Coordinates.x == 0)
				{
					mission->setDestinationNPC(npc);
					mission_dest.Coordinates = npc->mPosition;
					mission_dest.CellID = 0;
					mission_dest.PlanetCRC = BString(gWorldManager->getPlanetNameThis()).getCrc();
					mission->setDestination(mission_dest);
				}
				else if(mission_start.Coordinates.x == 0 && mission->getDestinationNPC() != npc)
				{
					mission->setStartNPC(npc);
					mission_start.Coordinates = npc->mPosition;
					mission_start.CellID = 0;
					mission_start.PlanetCRC = BString(gWorldManager->getPlanetNameThis()).getCrc();
					mission->setStart(mission_start);
					found = true;
				}

			}
		}
	}

	//Creator
	mission->setCreator(creators[gRandom->getRand() % 9]);

    //Mission Title
	sprintf(mt,"m%dt",mission_num);

	mission->setTitleFile(mission_deliver_hard[stf_file].mSTF);
	mission->setTitle(mt);

	//Mission Description
	sprintf(md,"m%dd",mission_num);

	mission->setDetailFile(mission_deliver_hard[stf_file].mSTF);
	mission->setDetail(md);

   //Diffaculty
	mission->setDifficulty((gRandom->getRand() % 10)+3);

	//Payment
	mission->setReward((gRandom->getRand() % 300)+50);

	//Mission Target
	mission->setTargetModel(0xE191DBAB); //crc = object/tangible/mission/shared_mission_datadisk.iff

return mission;
}
void ObjectController::_handleNPCConversationStart(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties)
{
	PlayerObject*	player	= dynamic_cast<PlayerObject*>(mObject);
	NPCObject*		npc		= dynamic_cast<NPCObject*>(gWorldManager->getObjectById(targetId));

	if(!npc)
	{
		DLOG(info) << "ObjController::_handleNPCConversationStart: Couldn't find object " << targetId;
		return;
	}

	// in range check
	uint64 playerParentId	= player->getParentId();
	uint64 npcParentId		= npc->getParentId();
	bool   inRange			= true;

	uint64 playerBuildingId = 0;
	uint64 npcBuildingId = 0;

	//get building Ids if they are in buildings
	if(playerParentId)
	{
		playerBuildingId = gWorldManager->getObjectById(playerParentId)->getParentId();
	}
		
	if(npcParentId)
	{
		npcBuildingId	= gWorldManager->getObjectById(npcParentId)->getParentId();
	}

	// not inside same parent, or out of range
	float distance = glm::distance(player->getWorldPosition(), npc->getWorldPosition());
	if ((npcBuildingId != playerParentId) || distance > 10.0f)
	{
		inRange = false;
	}

	// we are out of range
    if(!inRange)
    {
        float distance = glm::distance(player->mPosition, npc->mPosition);
        char buffer[100];
        sprintf(buffer, "You are out of range (%f m).", distance);
        BString msg(buffer);
        msg.convert(BSTRType_Unicode16);
        gMessageLib->SendSystemMessage(msg.getUnicode16(), player);
        // gMessageLib->sendSystemMessage(player,L"","system_msg","out_of_range");
        return;
    }

    //check to see if he is part of a mission
    /*if(gMissionManager->checkDeliverMission(player,npc) ||
            gMissionManager->checkCraftingMission(player,npc)
        ) return;*/

    // we don't want him to talk
    if(npc->hasInternalAttribute("no_chat"))
        return;

    // initiate a conversation dialog
    if(npc->hasInternalAttribute("base_conversation"))
    {
        // Let the npc have your attention, and some npc-movement.
        npc->prepareConversation(player);
        gConversationManager->startConversation(npc,player);
    }

    // say some chatter
    else
    {
        // spam protection
        uint64 localTime = Anh_Utils::Clock::getSingleton()->getLocalTime();
        if(npc->getLastConversationTarget() == player->getId())
        {
            if(localTime - npc->getLastConversationRequest() < NPC_CHAT_SPAM_PROTECTION_TIME)
            {
                return;
            }
            else
            {
                npc->setLastConversationRequest(localTime);
            }
        }
        else
        {
            npc->setLastConversationRequest(localTime);
            npc->setLastConversationTarget(player->getId());
        }

        // Let the npc have your attention, and some npc-movement.
        // Nope... npc->prepareConversation(player);
        std::wstring npc_chat;
        uint32_t animation = 0;

        // say a specific preset sentence
        if(npc->hasInternalAttribute("npc_chat"))	{
            std::string tmp = npc->getInternalAttribute<std::string>("npc_chat");
            npc_chat = std::wstring(tmp.begin(), tmp.end());
        } else {
            std::pair<std::wstring,uint32> chat = gWorldManager->getRandNpcChatter();

            npc_chat  = chat.first;
            animation = chat.second;
        }

        if (!gWorldConfig->isInstance()) {
            gMessageLib->SendSpatialChat(npc, npc_chat, player);

            if (animation) gMessageLib->sendCreatureAnimation(npc,gWorldManager->getNpcConverseAnimation(animation));
        } else {
            gMessageLib->SendSpatialChat(npc, npc_chat, player);

            if (animation) gMessageLib->sendCreatureAnimation(npc,gWorldManager->getNpcConverseAnimation(animation), player);
        }
    }
    
    
        
}
NPCObject* NonPersistentNpcFactory::createNonPersistentNpc(DatabaseResult* result, uint64 templateId, uint64 npcNewId, uint32 familyId, uint64 controllingObject)
{
	NPCObject*		npc;

	switch(familyId)
	{
		case NpcFamily_Trainer:
		{
			npc	= new Trainer();
		}
		break;		

		case NpcFamily_Filler:
		{
			npc	= new FillerNPC();
		}
		break;

		case NpcFamily_QuestGiver:
		{
			npc	= new QuestGiver();
		}
		break;

		case NpcFamily_AttackableObject:
		{
			// Stuff like Debris.
			npc	= new AttackableStaticNpc();
		}
		break;

		case NpcFamily_AttackableCreatures:
		{
			// gLogger->logMsgF("NonPersistentNpcFactory::_createNonPersistentNpc() Created a NpcFamily_AttackableCreatures", MSG_NORMAL);
			// Stuff like npc's and womp rats :).
			npc	= new AttackableCreature(templateId);
		}
		break;

		case NpcFamily_NaturalLairs:
		{
			// First time lairs.
			// gLogger->logMsgF("NonPersistentNpcFactory::createNonPersistentNpc() Created a NpcFamily_NaturalLairs", MSG_NORMAL);

			//Lairs are not supported here, at least not yet.
			assert(false && "NonPersistentNpcFactory::createNonPersistent NpcFamily_NaturalLairs Lairs are not supported here yet.");
			npc	= new LairObject(templateId);
		}
		break;

		default:
		{
			gLogger->logMsgF("NonPersistentNpcFactory::createNonPersistent unknown Family %u",MSG_HIGH,familyId);
			assert(false && "NonPersistentNpcFactory::createNonPersistent unknown family");
			npc = new NPCObject();
		}
		break;
	}

	// Set the new temporarily id.
	npc->setId(npcNewId);

	// Register object with WorldManager.
	gWorldManager->addObject(npc, true);

	Inventory*	npcInventory = new Inventory();
	npcInventory->setCapacity(50);//we want to be able to fill something in our inventory
	npcInventory->setParent(npc);

	uint64 count = result->getRowCount();

	result->GetNextRow(mNonPersistentNpcBinding,(void*)npc);

	// The template for this creature, in case of a respawn.
	npc->mNpcTemplateId = templateId;

	// Should bet fetched from attributes, these will do as defaults.
	npc->mHam.mHealth.setCurrentHitPoints(500);
	npc->mHam.mAction.setCurrentHitPoints(500);
	npc->mHam.mMind.setCurrentHitPoints(500);
	npc->mHam.calcAllModifiedHitPoints();

	// inventory
	npcInventory->setId(npc->mId + 1);
	npcInventory->setParentId(npc->mId);
	npcInventory->setModelString("object/tangible/inventory/shared_creature_inventory.iff");
	
	npcInventory->setName("inventory");
	npcInventory->setNameFile("item_n");
	npcInventory->setTangibleGroup(TanGroup_Inventory);
	npcInventory->setTangibleType(TanType_CreatureInventory);
	npc->mEquipManager.addEquippedObject(CreatureEquipSlot_Inventory,npcInventory);

	if (npc->getNpcFamily() == NpcFamily_AttackableObject)
	{
		// Dynamic spawned pve-enabled "static" creatures like debris.
		npc->setType(ObjType_Creature);
		npc->setCreoGroup(CreoGroup_AttackableObject);

		npc->mTypeOptions = 0x0;
		
		// Let's start as non-attackable. 
		// npc->togglePvPStateOn((CreaturePvPStatus)(CreaturePvPStatus_Attackable));
	}
	else if (npc->getNpcFamily() == NpcFamily_NaturalLairs)
	{
		//Lairs are not supported here, at least not yet.
		assert(false && "NonPersistentNpcFactory::createNonPersistent NpcFamily_NaturalLairs Lairs not supported here yet");

		// Dynamic spawned pve-enabled "static" creatures like lairs.
		npc->setType(ObjType_Creature);

		// This will ensure the use of the single H(am) bar.
		npc->setCreoGroup(CreoGroup_AttackableObject);	
		npc->mTypeOptions = 0x0;
		npc->togglePvPStateOn((CreaturePvPStatus)(CreaturePvPStatus_Attackable));

		// npc->mHam.mHealth.setCurrentHitPoints(5000);
		// npc->mHam.mHealth.setMaxHitPoints(5000);
		// npc->mHam.mHealth.setBaseHitPoints(5000);
		// npc->mHam.calcAllModifiedHitPoints();

		// Let's put some credits in the inventory.
		// npcInventory->setCredits((gRandom->getRand()%25) + 10);
		// gLogger->logMsgF("NonPersistentNpcFactory::createNonPersistentNpc() WOW, I'm a lair", MSG_NORMAL);
	}
	else if (npc->getNpcFamily() == NpcFamily_AttackableCreatures)
	{
		// Dynamic spawned pve-enabled creatures.
		npc->setType(ObjType_Creature);
		npc->setCreoGroup(CreoGroup_Creature);

		npc->mTypeOptions = 0x0;

		if (gWorldConfig->isTutorial())
		{
			npc->togglePvPStateOn((CreaturePvPStatus)(CreaturePvPStatus_Attackable + CreaturePvPStatus_Aggressive + CreaturePvPStatus_Enemy ));
		}
		else
		{
			npc->togglePvPStateOn((CreaturePvPStatus)(CreaturePvPStatus_Attackable));
		}

		AttackableCreature* attackableNpc = dynamic_cast<AttackableCreature*>(npc);
		assert(attackableNpc && "NonPersistentNpcFactory::createNonPersistent unable to cast npc to AttackableCreature instance");

		// Fix this later
		// Also set the owner (lair) who's controlling this creature.
		attackableNpc->setLairId(controllingObject);

		Weapon* defaultWeapon = new Weapon();
		defaultWeapon->setId(gWorldManager->getRandomNpId());

		defaultWeapon->setParentId(npc->mId);
		defaultWeapon->setModelString("object/weapon/melee/unarmed/shared_unarmed_default_player.iff");
		defaultWeapon->setGroup(WeaponGroup_Unarmed);
		defaultWeapon->setEquipSlotMask(CreatureEquipSlot_Weapon);
		defaultWeapon->addInternalAttribute("weapon_group","1");
 
		npc->mEquipManager.setDefaultWeapon(defaultWeapon);
		npc->mEquipManager.equipDefaultWeapon();

// Weapon to use should be gotten from attibutes or whereever we find that kind of info.
		// This little fellow may need a gun.
		Weapon* pistol = new Weapon();
		pistol->setId(gWorldManager->getRandomNpId());

		pistol->setParentId(npc->mId);
		pistol->setModelString("object/weapon/ranged/pistol/shared_pistol_cdef.iff");
		pistol->setGroup(WeaponGroup_Pistol);
		pistol->setEquipSlotMask(CreatureEquipSlot_Weapon);
		pistol->addInternalAttribute("weapon_group","32");
		attackableNpc->setPrimaryWeapon(pistol);

		
		// A saber can be handy, too.
		Weapon* saber = new Weapon();
		saber->setId(gWorldManager->getRandomNpId());

		saber->setParentId(npc->mId);
		saber->setModelString("object/weapon/melee/sword/shared_sword_lightsaber_vader.iff");
		saber->setGroup(WeaponGroup_2h);
		saber->setEquipSlotMask(CreatureEquipSlot_Weapon);
		saber->addInternalAttribute("weapon_group","4");
		attackableNpc->setSecondaryWeapon(saber);

		if (gWorldConfig->isTutorial())
		{
			attackableNpc->equipPrimaryWeapon();
		}
		else
		{
			// attackableNpc->equipSecondaryWeapon();
		}

// Should be handle by "loot manager"
		// Let's put some credits in the inventory.
		npcInventory->setCredits((gRandom->getRand()%25) + 10);
	}
	else
	{
		npc->mTypeOptions = 0x108;
	}
	npc->setLoadState(LoadState_Attributes);

	// Save default direction, since player can make the npc change heading.
	// Can't apply this to a dynamically created npc.
	// npc->storeDefaultDirection();
	return npc;
}
void NonPersistentNpcFactory::handleDatabaseJobComplete(void* ref,DatabaseResult* result)
{
	
	QueryNonPersistentNpcFactory* asyncContainer = reinterpret_cast<QueryNonPersistentNpcFactory*>(ref);

	switch(asyncContainer->mQueryType)
	{
		case NonPersistentNpcQuery_Attributes:
		{
			// gLogger->logMsgF("NonPersistentNpcFactory::handleDatabaseJobComplete() AT NonPersistentNpcQuery_Attributes:", MSG_NORMAL);
			Object* object = gWorldManager->getObjectById(asyncContainer->mId);
			if (object)
			{
				_buildAttributeMap(object,result);
				if (object->getLoadState() == LoadState_Loaded && asyncContainer->mOfCallback)
				{
					// gLogger->logMsgF("NonPersistentNpcFactory::handleDatabaseJobComplete() Invoking mOfCallback->handleObjectReady(npc)", MSG_NORMAL);
					asyncContainer->mOfCallback->handleObjectReady(object);
				}
				else
				{
					// gLogger->logMsgF("NonPersistentNpcFactory::handleDatabaseJobComplete() Invoking NOTHING", MSG_NORMAL);
				}
			}
			else
			{
				gLogger->logMsgF("NonPersistentNpcFactory::handleDatabaseJobComplete() Object is GONE", MSG_NORMAL);
			}
		}
		break;
//=============================================================================
//
//	Upgrade version for use of the correct DB.
//
//=============================================================================

		case NonPersistentNpcQuery_LairTemplate:
		{
			// gLogger->logMsgF("NonPersistentNpcFactory::handleDatabaseJobComplete() AT NonPersistentNpcQuery_LairTemplate:", MSG_NORMAL);

			NpcLairEntityEx lair;

			DataBinding* lairSpawnBinding = mDatabase->CreateDataBinding(9);
			lairSpawnBinding->addField(DFT_uint64,offsetof(NpcLairEntityEx,mCreatureSpwanRegion),8,0);
			lairSpawnBinding->addField(DFT_uint64,offsetof(NpcLairEntityEx,mTemplateId),8,1);
			lairSpawnBinding->addField(DFT_uint32,offsetof(NpcLairEntityEx,mCreatureGroup),4,2);
			lairSpawnBinding->addField(DFT_uint32,offsetof(NpcLairEntityEx,mNumberOfLairs),4,3);
			lairSpawnBinding->addField(DFT_float,offsetof(NpcLairEntityEx,mSpawnPosX),4,4);
			lairSpawnBinding->addField(DFT_float,offsetof(NpcLairEntityEx,mSpawnPosZ),4,5);
			lairSpawnBinding->addField(DFT_float,offsetof(NpcLairEntityEx,mSpawnDirY),4,6);
			lairSpawnBinding->addField(DFT_float,offsetof(NpcLairEntityEx,mSpawnDirW),4,7);
			lairSpawnBinding->addField(DFT_uint32,offsetof(NpcLairEntityEx,mFamily),4,8);
			
			DataBinding* lairSpawnNpcBinding = mDatabase->CreateDataBinding(4);
			lairSpawnNpcBinding->addField(DFT_bstring,offsetof(NPCObject,mModel),255,9);
			lairSpawnNpcBinding->addField(DFT_bstring,offsetof(NPCObject,mSpecies),255,10);
			lairSpawnNpcBinding->addField(DFT_bstring,offsetof(NPCObject,mSpeciesGroup),255,11);
			lairSpawnNpcBinding->addField(DFT_bstring,offsetof(NPCObject,mFaction),32,12);
					
			uint64 count = result->getRowCount();

			result->GetNextRow(lairSpawnBinding,&lair);

			// Let's create the lair.
		
			// We save the lairs-type... that's kinda a template for the complete lair.
			LairObject* npc	= new LairObject(asyncContainer->mTemplateId);

			// Set the new if of this temp object.
			npc->setId(asyncContainer->mId);

			// Register object with WorldManager.
			gWorldManager->addObject(npc, true);

			// May need the height also, in case of pre set (fixed) spawn position.
			npc->mPosition.x = lair.mSpawnPosX;
			npc->mPosition.z = lair.mSpawnPosZ;

			if (npc->getParentId() == 0)
			{
				// Heightmap only works outside.
				npc->mPosition.y = npc->getHeightAt2DPosition(lair.mSpawnPosX, lair.mSpawnPosZ, true);
			}
			else
			{
				// We do not have support for handling creatures inside.
				assert(false && "NonPersistentNpcFactory::handleDatabaseJobComplete NonPersistentNpcQuery_LairTemplate No support for handling creatures inside");
				npc->mPosition.y = 0;
			}
			
			npc->mDirection.y = lair.mSpawnDirY;
			npc->mDirection.w = lair.mSpawnDirW;

			// Let's get the spawn area.
			const Anh_Math::Rectangle spawnArea = gWorldManager->getSpawnArea(lair.mCreatureSpwanRegion);

			// lair.mCreatureSpwanRegion
			npc->setSpawnArea(spawnArea); 

			result->ResetRowIndex();
			result->GetNextRow(lairSpawnNpcBinding,(void*)npc );
			
			mDatabase->DestroyDataBinding(lairSpawnBinding);
			mDatabase->DestroyDataBinding(lairSpawnNpcBinding);

			Inventory*	npcInventory = new Inventory();
			npcInventory->setParent(npc);

			npc->mHam.mHealth.setCurrentHitPoints(500);
			npc->mHam.mAction.setCurrentHitPoints(500);
			npc->mHam.mMind.setCurrentHitPoints(500);
			npc->mHam.calcAllModifiedHitPoints();

			// inventory
			npcInventory->setId(npc->mId + 1);
			npcInventory->setParentId(npc->mId);
			npcInventory->setModelString("object/tangible/inventory/shared_creature_inventory.iff");
			
			npcInventory->setName("inventory");
			npcInventory->setNameFile("item_n");
			npcInventory->setTangibleGroup(TanGroup_Inventory);
			npcInventory->setTangibleType(TanType_CreatureInventory);
			npc->mEquipManager.addEquippedObject(CreatureEquipSlot_Inventory,npcInventory);

			npc->setType(ObjType_Creature);

			// This will ensure the use of the single H(am) bar.
			npc->setCreoGroup(CreoGroup_AttackableObject);	
			npc->mTypeOptions = 0x0;
			npc->togglePvPStateOn((CreaturePvPStatus)(CreaturePvPStatus_Attackable));

			// gLogger->logMsgF("NonPersistentNpcFactory::handleDatabaseJobComplete() Attempting to get the creature templates for group %u used by this lair.", MSG_NORMAL, lair.mCreatureGroup);

			QueryNonPersistentNpcFactory* asContainer = new QueryNonPersistentNpcFactory(asyncContainer->mOfCallback, NonPersistentNpcQuery_LairCreatureTemplates, asyncContainer->mTemplateId, asyncContainer->mId);
			// Do not transfer object refs, use the handle, i.e. asyncContainer->mId
			// asContainer->mObject = npc;

			mDatabase->ExecuteSqlAsync(this, asContainer,
							"SELECT creature_groups.creature_id "
							"FROM creature_groups "
							"WHERE creature_groups.creature_group_id=%u;",lair.mCreatureGroup);

		}
		break;

		case NonPersistentNpcQuery_LairCreatureTemplates:
		{
			// Get the lair object.
			LairObject* npc = dynamic_cast<LairObject*>(gWorldManager->getObjectById(asyncContainer->mId));
			assert(npc && "NonPersistentNpcFactory::handleDatabaseJobComplete NonPersistentNpcQuery_LairCreatureTemplates WorldManager unable to find object id");

			uint64	creatureTemplateId;
			DataBinding* creatureTemplateBinding = mDatabase->CreateDataBinding(1);
			creatureTemplateBinding->addField(DFT_uint64,0,8,0);

			uint64 count = result->getRowCount();

			int32	spawnRateInc = 100/static_cast<uint32>(count);
			int32	spawnRate = -1;

			for (uint64 i = 0; i < count; i++)
			{
				result->GetNextRow(creatureTemplateBinding, &creatureTemplateId);
				// gLogger->logMsgF("NonPersistentNpcFactory::handleDatabaseJobComplete() Creature template %"PRIu64" used by lair ", MSG_NORMAL, creatureTemplateId);
				npc->setCreatureTemplate((uint32)i, creatureTemplateId);

				spawnRate += spawnRateInc;
				npc->setCreatureSpawnRate((uint32)i, (uint32)spawnRate);
			}
			if (count > 0 && spawnRate < 99)
			{
				npc->setCreatureSpawnRate(static_cast<uint32>(count) - 1, 99);
			}
			mDatabase->DestroyDataBinding(creatureTemplateBinding);


			// gLogger->logMsgF("NonPersistentNpcFactory::handleDatabaseJobComplete() Attempting to get the Attributes", MSG_NORMAL);

			QueryNonPersistentNpcFactory* asContainer = new QueryNonPersistentNpcFactory(asyncContainer->mOfCallback,NonPersistentNpcQuery_Attributes, 0, npc->getId());

			mDatabase->ExecuteSqlAsync(this,asContainer,"SELECT attributes.name,lair_attributes.value,attributes.internal"
				" FROM lair_attributes"
				" INNER JOIN attributes ON (lair_attributes.attribute_id = attributes.id)"
				" WHERE lair_attributes.lair_id = %"PRIu64" ORDER BY lair_attributes.order", asyncContainer->mTemplateId);
		}
		break;

		case NonPersistentNpcQuery_NpcTemplate:
		{
			// gLogger->logMsgF("NonPersistentNpcFactory::handleDatabaseJobComplete() AT NonPersistentNpcQuery_NpcTemplate:", MSG_NORMAL);
			NPCObject* npc = _createNonPersistentNpc(result, asyncContainer->mTemplateId, asyncContainer->mId, asyncContainer->mParentObjectId);
			assert(npc);

			// Spawn related data.
			npc->setCellIdForSpawn(asyncContainer->mSpawnCellId);
			npc->setSpawnPosition(asyncContainer->mSpawnPosition);
			npc->setSpawnDirection(asyncContainer->mSpawnDirection);
			npc->setRespawnDelay(asyncContainer->mRespawnDelay);

			if( npc->getLoadState() == LoadState_Loaded && asyncContainer->mOfCallback)
			{
				// gLogger->logMsgF("NonPersistentNpcFactory::handleDatabaseJobComplete() Invoking mOfCallback->handleObjectReady(npc)", MSG_NORMAL);
				asyncContainer->mOfCallback->handleObjectReady(npc);
			}
			else if (npc->getLoadState() == LoadState_Attributes)
			{
				QueryNonPersistentNpcFactory* asContainer = new QueryNonPersistentNpcFactory(asyncContainer->mOfCallback,NonPersistentNpcQuery_Attributes, 0, npc->getId());
				
				// gLogger->logMsgF("NonPersistentNpcFactory::handleDatabaseJobComplete() Invoking NonPersistentNpcQuery_Attributes NPC ID = %"PRIu64"", MSG_NORMAL, npc->getId());

				mDatabase->ExecuteSqlAsync(this,asContainer,"SELECT attributes.name,non_persistent_npc_attributes.value,attributes.internal"
					" FROM non_persistent_npc_attributes"
					" INNER JOIN attributes ON (non_persistent_npc_attributes.attribute_id = attributes.id)"
					" WHERE non_persistent_npc_attributes.npc_id = %"PRIu64" ORDER BY non_persistent_npc_attributes.order", asyncContainer->mTemplateId);
			}
		}
		break;

		default:
		{
			gLogger->logMsgF("NonPersistentNpcFactory::handleDatabaseJobComplete() UNKNOWN query = %u\n", MSG_NORMAL, asyncContainer->mQueryType);
		}
		break;
	}

	delete asyncContainer;
}