Exemplo n.º 1
0
void CAIWeaponAbstract::DefaultReload(CAI* pAI)
{
	if (!m_pWeapon)
	{
		return;
	}

	if (pAI)
	{
		pAI->GetAIWorldState()->SetWSProp( kWSK_WeaponLoaded, pAI->GetHOBJECT(), kWST_bool, true );
	}

	m_eFiringState = kAIFiringState_Reloading;
	UpdateWeaponAnimation(pAI);

	if( m_pWeapon->GetAmmoInClip() > 0 )
	{
		return;
	}

	m_pWeapon->ReloadClip( false );

	// Keep track of reload counts on the blackboard.

	uint32 nRounds = pAI->GetAIBlackBoard()->GetBBRoundsFired();
	pAI->GetAIBlackBoard()->SetBBRoundsFired( nRounds + 1 );

	// After a reload we may not have any ammo in our reserves.
	if (m_pAIWeaponRecord && m_pAIWeaponRecord->bAllowAmmoGeneration)
	{
		m_pWeapon->GetArsenal()->AddAmmo( m_pWeapon->GetAmmoRecord(), 999999 );
	}
}
Exemplo n.º 2
0
bool Inventory::SetEquippedSlot(ieWordSigned slotcode, ieWord header)
{
	EquippedHeader = header;

	//doesn't work if magic slot is used, refresh the magic slot just in case
	if (HasItemInSlot("",SLOT_MAGIC) && (slotcode!=SLOT_MAGIC-SLOT_MELEE)) {
		Equipped = SLOT_MAGIC-SLOT_MELEE;
		UpdateWeaponAnimation();
		return false;
	}

	//if it is an illegal code, make it fist
	if ((size_t) (slotcode+SLOT_MELEE)>Slots.size()) {
		slotcode=IW_NO_EQUIPPED;
	}

	//unequipping (fist slot will be used now)
	if (slotcode == IW_NO_EQUIPPED || !HasItemInSlot("",slotcode+SLOT_MELEE)) {
		if (Equipped != IW_NO_EQUIPPED) {
			RemoveSlotEffects( SLOT_MELEE+Equipped);
		}
		Equipped = IW_NO_EQUIPPED;
		//fist slot equipping effects
		AddSlotEffects(SLOT_FIST);
		UpdateWeaponAnimation();
		return true;
	}

	//equipping a weapon, but remove its effects first
	if (Equipped != IW_NO_EQUIPPED) {
		RemoveSlotEffects( SLOT_MELEE+Equipped);
	}

	Equipped = slotcode;
	int effects = core->QuerySlotEffects( SLOT_MELEE+Equipped );
	if (effects) {
		CREItem* item = GetSlotItem(SLOT_MELEE+Equipped);
		item->Flags|=IE_INV_ITEM_EQUIPPED;
		if (item->Flags & IE_INV_ITEM_CURSED) {
			item->Flags|=IE_INV_ITEM_UNDROPPABLE;
		}
		AddSlotEffects( SLOT_MELEE+Equipped);
	}
	UpdateWeaponAnimation();
	return true;
}
Exemplo n.º 3
0
void CAIWeaponAbstract::DefaultAim(CAI* pAI)
{
	if (pAI)
	{
		pAI->GetAnimationContext()->SetProp( kAPG_Action, kAP_ACT_Aim );
	}
	
	UpdateWeaponAnimation(pAI);
}
Exemplo n.º 4
0
bool CAIWeaponAbstract::DefaultFire(CAI* pAI, const LTVector& vTargetPos, bool bAnimatesReload)
{
	if( !( m_pWeapon && m_pAIWeaponRecord ) )
	{
		return false;
	}

	HOBJECT hTarget = pAI->GetAIBlackBoard()->GetBBTargetObject();

	// Get our fire position

	LTVector vFirePos = GetFirePosition(pAI);

	// Get our firing vector

	LTVector vDir = vTargetPos - vFirePos;
	vDir.Normalize();

	// Now fire the weapon

	WeaponFireInfo weaponFireInfo;
	static uint8 s_nCount = GetRandom( 0, 255 );
	s_nCount++;

	weaponFireInfo.hFiredFrom  = pAI->GetHOBJECT();
	weaponFireInfo.vPath       = vDir;
	weaponFireInfo.vFirePos    = vFirePos;
	weaponFireInfo.vFlashPos   = vFirePos;
	weaponFireInfo.hTestObj    = hTarget;
	weaponFireInfo.hFiringWeapon = m_pWeapon->GetModelObject();
	weaponFireInfo.nSeed		= (uint8)GetRandom( 2, 255 );
	weaponFireInfo.nPerturbCount = s_nCount;
	weaponFireInfo.nFireTimestamp = g_pLTServer->GetRealTimeMS( );
	weaponFireInfo.bLeftHandWeapon = ( LTStrIEquals( m_szFireSocketName.c_str( ), "LEFTHAND" ) );

	if( pAI->GetAIBlackBoard()->GetBBPerfectAccuracy() )
	{
		weaponFireInfo.fPerturb = 0.0f;
	}
	else 
	{
		weaponFireInfo.fPerturb = 1.f;
	}

	WeaponState eWeaponState = m_pWeapon->UpdateWeapon( weaponFireInfo, true );

	if( eWeaponState == W_FIRED )
	{
		UpdateWeaponAnimation( pAI );
	}

	if( m_pWeapon->GetAmmoInClip() == 0 )
	{
		// Automatically reload if:
		// 1) The AI has more ammo for this weapon and
		// 2) Either the AI is flagged to autoreload, or the weapon is flagged to not animation reloads.
		if( AIWeaponUtils::HasAmmo(pAI, m_pAIWeaponRecord->eAIWeaponType, !AIWEAP_CHECK_HOLSTER) 
			&& ( ( pAI->GetAIBlackBoard()->GetBBAutoReload() && m_pAIWeaponRecord->bAllowAutoReload ) || !bAnimatesReload) )
		{
			Reload(pAI);
		}
		else 
		{
			pAI->GetAIWorldState()->SetWSProp( kWSK_WeaponLoaded, pAI->GetHOBJECT(), kWST_bool, false );
		}
	}
	else 
	{
		pAI->GetAIWorldState()->SetWSProp( kWSK_WeaponLoaded, pAI->GetHOBJECT(), kWST_bool, true );
	}

	// If the primary weapon is now out of ammo, set the WeaponArmed 
	// worldstate to false.

	if( pAI->GetAIBlackBoard()->GetBBPrimaryWeaponType() == m_pAIWeaponRecord->eAIWeaponType
		&& !AIWeaponUtils::HasAmmo(pAI, m_pAIWeaponRecord->eAIWeaponType, !AIWEAP_CHECK_HOLSTER))
	{
		pAI->GetAIBlackBoard()->SetBBSelectAction(true);
	}

	return true;
}
Exemplo n.º 5
0
//this is the low level equipping
//all checks have been made previously
bool Inventory::EquipItem(unsigned int slot)
{
	ITMExtHeader *header;

	if (!Owner) {
		//maybe assertion too?
		return false;
	}
	CREItem *item = GetSlotItem(slot);
	if (!item) {
		return false;
	}

	int weaponslot;

	// add effects of an item just being equipped to actor's effect queue
	int effect = core->QuerySlotEffects( slot );
	Item *itm = gamedata->GetItem(item->ItemResRef);
	if (!itm) {
		printf("Invalid item Equipped: %s Slot: %d\n", item->ItemResRef, slot);
		return false;
	}
	switch (effect) {
	case SLOT_EFFECT_LEFT:
		//no idea if the offhand weapon has style, or simply the right
		//hand style is dominant
		UpdateShieldAnimation(itm);
		break;
	case SLOT_EFFECT_MELEE:
		//if weapon is ranged, then find quarrel for it and equip that
		slot -= SLOT_MELEE;
		weaponslot = slot;
		EquippedHeader = 0;
		header = itm->GetExtHeader(EquippedHeader);
		if (header && header->AttackType == ITEM_AT_BOW) {
			//find the ranged projectile associated with it.
			slot = FindRangedProjectile(header->ProjectileQualifier);
			EquippedHeader = itm->GetWeaponHeaderNumber(true);
		} else if (header && header->AttackType == ITEM_AT_PROJECTILE) {
			EquippedHeader = itm->GetWeaponHeaderNumber(true);
		} else {
			EquippedHeader = itm->GetWeaponHeaderNumber(false);
		}
		header = itm->GetExtHeader(EquippedHeader);
		if (header) {
			SetEquippedSlot(slot, EquippedHeader);
			if (slot != IW_NO_EQUIPPED) {
				Owner->SetupQuickSlot(ACT_WEAPON1+weaponslot, slot+SLOT_MELEE, EquippedHeader);
			}
			effect = 0; // SetEquippedSlot will already call AddSlotEffects
			UpdateWeaponAnimation();
		}
		break;
	case SLOT_EFFECT_MISSILE:		
		//Get the ranged header of the projectile (so we theoretically allow shooting of daggers)
		EquippedHeader = itm->GetWeaponHeaderNumber(true);
		header = itm->GetExtHeader(EquippedHeader);
		if (header) {
			weaponslot = FindTypedRangedWeapon(header->ProjectileQualifier);
			if (weaponslot != SLOT_FIST) {
				weaponslot -= SLOT_MELEE;
				SetEquippedSlot((ieWordSigned) (slot-SLOT_MELEE), EquippedHeader);
				//It is unsure if we can have multiple equipping headers for bows/arrow
				//It is unclear which item's header index should go there
				Owner->SetupQuickSlot(ACT_WEAPON1+weaponslot, slot, 0);
			}
			UpdateWeaponAnimation();
		}
		break;
	case SLOT_EFFECT_HEAD:
		Owner->SetUsedHelmet(itm->AnimationType);
		break;
	case SLOT_EFFECT_ITEM:
		//adjusting armour level if needed
		{
			int l = itm->AnimationType[0]-'1';
			if (l>=0 && l<=3) {
				Owner->SetBase(IE_ARMOR_TYPE, l);
			} else {
				UpdateShieldAnimation(itm);
			}
		}
		break;
	}
	gamedata->FreeItem(itm, item->ItemResRef, false);
	if (effect) {
		if (item->Flags & IE_INV_ITEM_CURSED) {
			item->Flags|=IE_INV_ITEM_UNDROPPABLE;
		}
		AddSlotEffects( slot );
	}
	return true;
}
Exemplo n.º 6
0
void Inventory::KillSlot(unsigned int index)
{
	if (InventoryType==INVENTORY_HEAP) {
		Slots.erase(Slots.begin()+index);
		return;
	}
	CREItem *item = Slots[index];
	if (!item) {
		return;
	}

	//the used up item vanishes from the quickslot bar
	if (Owner->InParty) {
		core->SetEventFlag( EF_ACTION );
	}

	Slots[index] = NULL;
 	int effect = core->QuerySlotEffects( index );
	if (!effect) {
		return;
	}
	RemoveSlotEffects( index );
	Item *itm = gamedata->GetItem(item->ItemResRef);
	//this cannot happen, but stuff happens!
	if (!itm) {
		return;
	}
	ItemExcl &= ~itm->ItemExcl;

	switch (effect) {
		case SLOT_EFFECT_LEFT:
			UpdateShieldAnimation(0);
			break;
		case SLOT_EFFECT_MISSILE:
			//getting a new projectile of the same type
			if (Equipped + SLOT_MELEE == (int) index) {
				if (Equipped < 0) {
					//always get the projectile weapon header (this quiver was equipped)
					ITMExtHeader *header = itm->GetWeaponHeader(true);
					Equipped = FindRangedProjectile(header->ProjectileQualifier);
					if (Equipped!=IW_NO_EQUIPPED) {
						EquipItem(Equipped+SLOT_MELEE);
					} else {
						EquipItem(SLOT_FIST);
					}
				}
			}
			UpdateWeaponAnimation();
			break;
		case SLOT_EFFECT_MELEE:
			// reset Equipped if it was the removed item
			if (Equipped+SLOT_MELEE == (int)index)
				Equipped = IW_NO_EQUIPPED;
			else if (Equipped < 0) {
				//always get the projectile weapon header (this is a bow, because Equipped is negative)
				ITMExtHeader *header = itm->GetWeaponHeader(true);
				if (header) {
					//find the equipped type
					int type = header->ProjectileQualifier;
					int weaponslot = FindTypedRangedWeapon(type);
					CREItem *item2 = Slots[weaponslot];
					if (item2) {
						Item *itm2 = gamedata->GetItem(item2->ItemResRef);
						if (itm2) {
							if (type == header->ProjectileQualifier) {
								Equipped = FindRangedProjectile(header->ProjectileQualifier);
								if (Equipped!=IW_NO_EQUIPPED) {
									EquipItem(Equipped+SLOT_MELEE);
								} else {
									EquipItem(SLOT_FIST);
								}
							}
							gamedata->FreeItem(itm2, item2->ItemResRef, false);
						}
					}
				}
			}
			// reset Equipped if it is a ranged weapon slot
			// but not magic weapon slot!

			UpdateWeaponAnimation();      
			break;
		case SLOT_EFFECT_HEAD:
			Owner->SetUsedHelmet("");
			break;
		case SLOT_EFFECT_ITEM:
			//remove the armor type only if this item is responsible for it
			if ((ieDword) (itm->AnimationType[0]-'1') == Owner->GetBase(IE_ARMOR_TYPE)) {
				Owner->SetBase(IE_ARMOR_TYPE, 0);
			}
			break;
	}
	gamedata->FreeItem(itm, item->ItemResRef, false);
}
Exemplo n.º 7
0
void Inventory::EquipBestWeapon(int flags)
{
	int i;
	int damage = -1;
	ieDword best_slot = SLOT_FIST;
	ITMExtHeader *header;
	CREItem *Slot;
	char AnimationType[2]={0,0};
	ieWord MeleeAnimation[3]={100,0,0};

	//cannot change equipment when holding magic weapons
	if (Equipped == SLOT_MAGIC-SLOT_MELEE) {
		return;
	}

	if (flags&EQUIP_RANGED) {
		for(i=SLOT_RANGED;i<LAST_RANGED;i++) {
			const Item *itm = GetItemPointer(i, Slot);
			if (!itm) continue;
 			//best ranged
			int tmp = itm->GetDamagePotential(true, header);
			if (tmp>damage) {
				best_slot = i;
				damage = tmp;
				memcpy(AnimationType,itm->AnimationType,sizeof(AnimationType) );
				memcpy(MeleeAnimation,header->MeleeAnimation,sizeof(MeleeAnimation) );
			}
			gamedata->FreeItem( itm, Slot->ItemResRef, false );
		}

		//ranged melee weapons like throwing daggers (not bows!)
		for(i=SLOT_MELEE;i<=LAST_MELEE;i++) {
			const Item *itm = GetItemPointer(i, Slot);
			if (!itm) continue;
			//best ranged
			int tmp = itm->GetDamagePotential(true, header);
			if (tmp>damage) {
				best_slot = i;
				damage = tmp;
				memcpy(AnimationType,itm->AnimationType,sizeof(AnimationType) );
				memcpy(MeleeAnimation,header->MeleeAnimation,sizeof(MeleeAnimation) );
			}
			gamedata->FreeItem( itm, Slot->ItemResRef, false );
		}
	}

	if (flags&EQUIP_MELEE) {
		for(i=SLOT_MELEE;i<=LAST_MELEE;i++) {
			const Item *itm = GetItemPointer(i, Slot);
			if (!itm) continue;
			//the Slot flag is enough for this
			//though we need animation type/damagepotential anyway
			if (Slot->Flags&IE_INV_ITEM_BOW) continue;
			//best melee
			int tmp = itm->GetDamagePotential(false, header);
			if (tmp>damage) {
				best_slot = i;
				damage = tmp;
				memcpy(AnimationType,itm->AnimationType,sizeof(AnimationType) );
				memcpy(MeleeAnimation,header->MeleeAnimation,sizeof(MeleeAnimation) );
			}
			gamedata->FreeItem( itm, Slot->ItemResRef, false );
		}
	}

	EquipItem(best_slot);
	UpdateWeaponAnimation();
}