当前位置: 首页>>代码示例>>C++>>正文


C++ BattleItem::getRules方法代码示例

本文整理汇总了C++中BattleItem::getRules方法的典型用法代码示例。如果您正苦于以下问题:C++ BattleItem::getRules方法的具体用法?C++ BattleItem::getRules怎么用?C++ BattleItem::getRules使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在BattleItem的用法示例。


在下文中一共展示了BattleItem::getRules方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: invClick

/**
 * Updates item info.
 * @param action Pointer to an action.
 */
void InventoryState::invClick(Action *action)
{
	BattleItem *item = _inv->getSelectedItem();
	_txtItem->setText(L"");
	_txtAmmo->setText(L"");
	_selAmmo->clear();
	if (item != 0)
	{
		if (item->getUnit() && item->getUnit()->getStatus() == STATUS_UNCONSCIOUS)
		{
			_txtItem->setText(item->getUnit()->getName(_game->getLanguage()));
		}
		else
		{
			if (_game->getSavedGame()->isResearched(item->getRules()->getRequirements()))
			{
				_txtItem->setText(_game->getLanguage()->getString(item->getRules()->getName()));
			}
			else
			{
				_txtItem->setText(_game->getLanguage()->getString("STR_ALIEN_ARTIFACT"));
			}
		}
		std::wstringstream ss;
		if (item->getAmmoItem() != 0 && item->needsAmmo())
		{
			ss << _game->getLanguage()->getString("STR_AMMO_ROUNDS_LEFT") << L'\x01' << item->getAmmoItem()->getAmmoQuantity();
			SDL_Rect r;
			r.x = 0;
			r.y = 0;
			r.w = RuleInventory::HAND_W * RuleInventory::SLOT_W;
			r.h = RuleInventory::HAND_H * RuleInventory::SLOT_H;
			_selAmmo->drawRect(&r, Palette::blockOffset(0)+8);
			r.x++;
			r.y++;
			r.w -= 2;
			r.h -= 2;
			_selAmmo->drawRect(&r, 0);
			item->getAmmoItem()->getRules()->drawHandSprite(_game->getResourcePack()->getSurfaceSet("BIGOBS.PCK"), _selAmmo);
		}
		else if (item->getAmmoQuantity() != 0 && item->needsAmmo())
		{
			ss << _game->getLanguage()->getString("STR_AMMO_ROUNDS_LEFT") << L'\x01' << item->getAmmoQuantity();
		}
		_txtAmmo->setText(ss.str());
	}
	if (_tu)
	{
		std::wstringstream ss;
		ss << _game->getLanguage()->getString("STR_TUS") << L'\x01' << _battleGame->getSelectedUnit()->getTimeUnits();
		_txtTus->setText(ss.str());
	}
}
开发者ID:alienjon,项目名称:OpenXcom,代码行数:57,代码来源:InventoryState.cpp

示例2: invClick

/**
 * Updates item info.
 * @param action Pointer to an action.
 */
void InventoryState::invClick(Action *)
{
	BattleItem *item = _inv->getSelectedItem();
	_txtItem->setText(L"");
	_txtAmmo->setText(L"");
	_selAmmo->clear();
	if (item != 0)
	{
		if (item->getUnit() && item->getUnit()->getStatus() == STATUS_UNCONSCIOUS)
		{
			_txtItem->setText(item->getUnit()->getName(_game->getLanguage()));
		}
		else
		{
			if (_game->getSavedGame()->isResearched(item->getRules()->getRequirements()))
			{
				_txtItem->setText(tr(item->getRules()->getName()));
			}
			else
			{
				_txtItem->setText(tr("STR_ALIEN_ARTIFACT"));
			}
		}
		std::wstring s;
		if (item->getAmmoItem() != 0 && item->needsAmmo())
		{
			s = tr("STR_AMMO_ROUNDS_LEFT").arg(item->getAmmoItem()->getAmmoQuantity());
			SDL_Rect r;
			r.x = 0;
			r.y = 0;
			r.w = RuleInventory::HAND_W * RuleInventory::SLOT_W;
			r.h = RuleInventory::HAND_H * RuleInventory::SLOT_H;
			_selAmmo->drawRect(&r, Palette::blockOffset(0)+8);
			r.x++;
			r.y++;
			r.w -= 2;
			r.h -= 2;
			_selAmmo->drawRect(&r, 0);
			item->getAmmoItem()->getRules()->drawHandSprite(_game->getResourcePack()->getSurfaceSet("BIGOBS.PCK"), _selAmmo);
		}
		else if (item->getAmmoQuantity() != 0 && item->needsAmmo())
		{
			s = tr("STR_AMMO_ROUNDS_LEFT").arg(item->getAmmoQuantity());
		}
		else if (item->getRules()->getBattleType() == BT_MEDIKIT)
		{
			s = tr("STR_MEDI_KIT_QUANTITIES_LEFT").arg(item->getPainKillerQuantity()).arg(item->getStimulantQuantity()).arg(item->getHealQuantity());
		}
		_txtAmmo->setText(s);
	}
	updateStats();
}
开发者ID:fibercube,项目名称:OpenXcom,代码行数:56,代码来源:InventoryState.cpp

示例3: getItem

/**
* Get the "main hand weapon" from the unit.
* @return Pointer to item.
*/
BattleItem *BattleUnit::getMainHandWeapon() const
{
	BattleItem *weaponRightHand = getItem("STR_RIGHT_HAND");
	BattleItem *weaponLeftHand = getItem("STR_LEFT_HAND");

	// if there is only one weapon, or only one weapon loaded (rules out grenades) it's easy:
	if (!weaponRightHand || !weaponRightHand->getAmmoItem() || !weaponRightHand->getAmmoItem()->getAmmoQuantity())
		return weaponLeftHand;
	if (!weaponLeftHand || !weaponLeftHand->getAmmoItem() || !weaponLeftHand->getAmmoItem()->getAmmoQuantity())
		return weaponRightHand;

	// otherwise pick the one with the least snapshot TUs
	int tuRightHand = weaponRightHand->getRules()->getTUSnap();
	int tuLeftHand = weaponRightHand->getRules()->getTUSnap();
	if (tuLeftHand >= tuRightHand)
	{
		return weaponRightHand;
	}
	else
	{
		return weaponLeftHand;
	}
}
开发者ID:ben0x539,项目名称:OpenXcom,代码行数:27,代码来源:BattleUnit.cpp

示例4: init

/**
 * init sequence:
 * - check if shot is valid
 * - calculate base accuracy
 */
void ProjectileFlyBState::init()
{
	if (_initialized) return;
	_initialized = true;

	BattleItem *weapon = _action.weapon;
	_projectileItem = 0;
	_autoshotCounter = 0;

	if (!weapon) // can't shoot without weapon
		return;

	if (!_parent->getSave()->getTile(_action.target)) // invalid target position
		return;

	if (_action.actor->getTimeUnits() < _action.TU && !_parent->dontSpendTUs())
	{
		_action.result = "STR_NOT_ENOUGH_TIME_UNITS";
		_parent->popState();
		return;
	}

	_unit = _action.actor;
	_ammo = weapon->getAmmoItem();
	if (_unit->isOut())
	{
		// something went wrong - we can't shoot when dead or unconscious
		_parent->popState();
		return;
	}

	// autoshot will default back to snapshot if it's not possible
	if (weapon->getRules()->getAccuracyAuto() == 0 && _action.type == BA_AUTOSHOT)
		_action.type = BA_SNAPSHOT;

	// snapshot defaults to "hit" if it's a melee weapon
	// (in case of reaction "shots" with a melee weapon)
	if (weapon->getRules()->getBattleType() == BT_MELEE && _action.type == BA_SNAPSHOT)
		_action.type = BA_HIT;

	switch (_action.type)
	{
	case BA_SNAPSHOT:
	case BA_AIMEDSHOT:
	case BA_AUTOSHOT:
	case BA_LAUNCH:
		if (_ammo == 0)
		{
			_action.result = "STR_NO_AMMUNITION_LOADED";
			_parent->popState();
			return;
		}
		if (_ammo->getAmmoQuantity() == 0)
		{
			_action.result = "STR_NO_ROUNDS_LEFT";
			_parent->popState();
			return;
		}
		break;
	case BA_THROW:
		if (!validThrowRange(&_action))
		{
			// out of range
			_action.result = "STR_OUT_OF_RANGE";
			_parent->popState();
			return;
		}
		_projectileItem = weapon;
		break;
	case BA_HIT:
		if (!validMeleeRange(&_action))
		{
			_action.result = "STR_THERE_IS_NO_ONE_THERE";
			_parent->popState();
			return;
		}
		break;
	case BA_PANIC:
	case BA_MINDCONTROL:
		_parent->statePushFront(new ExplosionBState(_parent, Position((_action.target.x*16)+8,(_action.target.y*16)+8,(_action.target.z*24)+10), weapon, _action.actor));
		return;
	default:
		_parent->popState();
		return;
	}

	if (createNewProjectile() == true)
	{
		BattleAction action;
		BattleUnit *potentialVictim = _parent->getSave()->getTile(_action.target)->getUnit();
		if (potentialVictim && potentialVictim->getFaction() != _unit->getFaction())
		{
			if (_parent->getSave()->getTileEngine()->checkReactionFire(_unit, &action, potentialVictim, false))
			{
				_parent->statePushBack(new ProjectileFlyBState(_parent, action));
//.........这里部分代码省略.........
开发者ID:Shugyousha,项目名称:OpenXcom,代码行数:101,代码来源:ProjectileFlyBState.cpp

示例5: think

/**
 * Animates the projectile (move to the next point in it's trajectory).
 * If the animation is finished the projectile sprite is removed from the map.
 * And this state is finished.
 */
void ProjectileFlyBState::think()
{
	/* TODO refactoring : store the projectile in this state, instead of getting it from the map each time? */
	if (_parent->getMap()->getProjectile() == 0)
	{
		if (_action.type == BA_AUTOSHOT && _autoshotCounter < 3 && !_action.actor->isOut() && _ammo->getAmmoQuantity() != 0)
		{
			createNewProjectile();
		}
		else
		{
			_parent->popState();
		}
	}
	else
	{
		if(!_parent->getMap()->getProjectile()->move())
		{
			// impact !
			if (_action.type == BA_THROW)
			{
				Position pos = _parent->getMap()->getProjectile()->getPosition(-1);
				pos.x /= 16;
				pos.y /= 16;
				pos.z /= 24;
				BattleItem *item = _parent->getMap()->getProjectile()->getItem();
				_parent->getResourcePack()->getSoundSet("BATTLE.CAT")->getSound(38)->play();

				if (Options::getBool("battleAltGrenade") && item->getRules()->getBattleType() == BT_GRENADE && item->getExplodeTurn() > 0)
				{
					// it's a hot grenade to explode immediately
					_parent->statePushFront(new ExplosionBState(_parent, _parent->getMap()->getProjectile()->getPosition(-1), item, _action.actor));
				}
				else
				{
					_parent->dropItem(pos, item);
				}
			}
			else if (_action.type == BA_LAUNCH && _action.waypoints.size() > 1 && _projectileImpact == -1)
			{
				_origin = _action.waypoints.front();
				_action.waypoints.pop_front();
				_action.target = _action.waypoints.front();
				// launch the next projectile in the waypoint cascade
				_parent->statePushBack(new ProjectileFlyBState(_parent, _action, _origin));
			}
			else
			{
				if (_action.type == BA_LAUNCH && _ammo->spendBullet() == false)
				{
					_parent->getSave()->removeItem(_ammo);
					_action.weapon->setAmmoItem(0);
				}

				if (_projectileImpact != 5) // out of map
				{
					int offset = 0;
					// explosions impact not inside the voxel but one step back
					if (_ammo && (
						_ammo->getRules()->getDamageType() == DT_HE ||
						_ammo->getRules()->getDamageType() == DT_IN))
					{
						offset = -1;
					}
					_parent->statePushFront(new ExplosionBState(_parent, _parent->getMap()->getProjectile()->getPosition(offset), _ammo, _action.actor));
				}
				else
				{
					_unit->aim(false);
					_parent->getMap()->cacheUnits();
				}
			}

			delete _parent->getMap()->getProjectile();
			_parent->getMap()->setProjectile(0);
		}
	}
}
开发者ID:Shugyousha,项目名称:OpenXcom,代码行数:83,代码来源:ProjectileFlyBState.cpp

示例6: init

/**
 * init sequence:
 * - check if shot is valid
 * - calculate base accuracy
 */
void ProjectileFlyBState::init()
{
	if (_initialized) return;
	_initialized = true;

	BattleItem *weapon = _action.weapon;
	_projectileItem = 0;

	if (!weapon) // can't shoot without weapon
	{
		_parent->popState();
		return;
	}

	if (!_parent->getSave()->getTile(_action.target)) // invalid target position
	{
		_parent->popState();
		return;
	}

	if (_parent->getPanicHandled() && _action.actor->getTimeUnits() < _action.TU)
	{
		_action.result = "STR_NOT_ENOUGH_TIME_UNITS";
		_parent->popState();
		return;
	}

	_unit = _action.actor;
	
	_ammo = weapon->getAmmoItem();
	
	if (_unit->isOut())
	{
		// something went wrong - we can't shoot when dead or unconscious
		_parent->popState();
		return;
	}

	// reaction fire
	if (_unit->getFaction() != _parent->getSave()->getSide())
	{
		// no ammo or target is dead: give the time units back and cancel the shot.
		if (_ammo == 0 || !_parent->getSave()->getTile(_action.target)->getUnit() || _parent->getSave()->getTile(_action.target)->getUnit()->isOut())
		{
			_unit->setTimeUnits(_unit->getTimeUnits() + _unit->getActionTUs(_action.type, _action.weapon));
			_parent->popState();
			return;
		}
	}

	// autoshot will default back to snapshot if it's not possible
	if (weapon->getRules()->getAccuracyAuto() == 0 && _action.type == BA_AUTOSHOT)
		_action.type = BA_SNAPSHOT;

	// snapshot defaults to "hit" if it's a melee weapon
	// (in case of reaction "shots" with a melee weapon)
	if (weapon->getRules()->getBattleType() == BT_MELEE && _action.type == BA_SNAPSHOT)
		_action.type = BA_HIT;

	switch (_action.type)
	{
	case BA_SNAPSHOT:
	case BA_AIMEDSHOT:
	case BA_AUTOSHOT:
	case BA_LAUNCH:
		if (_ammo == 0)
		{
			_action.result = "STR_NO_AMMUNITION_LOADED";
			_parent->popState();
			return;
		}
		if (_ammo->getAmmoQuantity() == 0)
		{
			_action.result = "STR_NO_ROUNDS_LEFT";
			_parent->popState();
			return;
		}
		break;
	case BA_THROW:
		if (!validThrowRange(&_action))
		{
			// out of range
			_action.result = "STR_OUT_OF_RANGE";
			_parent->popState();
			return;
		}
		_projectileItem = weapon;
		break;
	case BA_HIT:
		if (!_parent->getTileEngine()->validMeleeRange(_action.actor->getPosition(), _action.actor->getDirection(), _action.actor->getArmor()->getSize(), 0))
		{
			_action.result = "STR_THERE_IS_NO_ONE_THERE";
			_parent->popState();
			return;
		}
//.........这里部分代码省略.........
开发者ID:mydmitry,项目名称:OpenXcom,代码行数:101,代码来源:ProjectileFlyBState.cpp

示例7: think

/**
 * Animates the projectile (move to the next point in it's trajectory).
 * If the animation is finished the projectile sprite is removed from the map.
 * And this state is finished.
 */
void ProjectileFlyBState::think()
{
	/* TODO refactoring : store the projectile in this state, instead of getting it from the map each time? */
	if (_parent->getMap()->getProjectile() == 0)
	{
		if (_action.type == BA_AUTOSHOT && _action.autoShotCounter < 3 && !_action.actor->isOut() && _ammo->getAmmoQuantity() != 0)
		{
			createNewProjectile();
		}
		else
		{
			if (_action.cameraPosition.z != -1)
			{
				_parent->getMap()->getCamera()->setMapOffset(_action.cameraPosition);
			}
			if (_action.type != BA_PANIC && _action.type != BA_MINDCONTROL)
			{
				_parent->getTileEngine()->checkReactionFire(_unit);
			}
			_unit->abortTurn();
			_parent->popState();
		}
	}
	else
	{
		if(!_parent->getMap()->getProjectile()->move())
		{
			// impact !
			if (_action.type == BA_THROW)
			{
				Position pos = _parent->getMap()->getProjectile()->getPosition(-1);
				pos.x /= 16;
				pos.y /= 16;
				pos.z /= 24;
				BattleItem *item = _parent->getMap()->getProjectile()->getItem();
				_parent->getResourcePack()->getSound("BATTLE.CAT", 38)->play();

				if (Options::getBool("battleInstantGrenade") && item->getRules()->getBattleType() == BT_GRENADE && item->getExplodeTurn() != 0 && item->getExplodeTurn() <= _parent->getSave()->getTurn())
				{
					// it's a hot grenade to explode immediately
					_parent->statePushFront(new ExplosionBState(_parent, _parent->getMap()->getProjectile()->getPosition(-1), item, _action.actor));
				}
				else
				{
					_parent->dropItem(pos, item);
				}
			}
			else if (_action.type == BA_LAUNCH && _action.waypoints.size() > 1 && _projectileImpact == -1)
			{
				_origin = _action.waypoints.front();
				_action.waypoints.pop_front();
				_action.target = _action.waypoints.front();
				// launch the next projectile in the waypoint cascade
				_parent->statePushBack(new ProjectileFlyBState(_parent, _action, _origin));
			}
			else
			{
				if (_ammo && _action.type == BA_LAUNCH && _ammo->spendBullet() == false)
				{
					_parent->getSave()->removeItem(_ammo);
					_action.weapon->setAmmoItem(0);
				}

				if (_projectileImpact != 5) // out of map
				{
					int offset = 0;
					// explosions impact not inside the voxel but two steps back (projectiles generally move 2 voxels at a time)
					if (_ammo && (
						_ammo->getRules()->getDamageType() == DT_HE ||
						_ammo->getRules()->getDamageType() == DT_IN))
					{
						offset = -2;
					}
					_parent->statePushFront(new ExplosionBState(_parent, _parent->getMap()->getProjectile()->getPosition(offset), _ammo, _action.actor, 0, (_action.type != BA_AUTOSHOT || _action.autoShotCounter == 3|| !_action.weapon->getAmmoItem())));
					if (_projectileImpact == 4)
					{
						BattleUnit *victim = _parent->getSave()->getTile(_parent->getMap()->getProjectile()->getPosition(offset) / Position(16,16,24))->getUnit();
						if (victim && !victim->isOut() && victim->getFaction() == FACTION_HOSTILE)
						{
							AggroBAIState *aggro = dynamic_cast<AggroBAIState*>(victim->getCurrentAIState());
							if (aggro == 0)
							{
								aggro = new AggroBAIState(_parent->getSave(), victim);
								victim->setAIState(aggro);
							}
							aggro->setAggroTarget(_action.actor);
						}
					}
				}
				else if (_action.type != BA_AUTOSHOT || _action.autoShotCounter == 3 || !_action.weapon->getAmmoItem())
				{
					_unit->aim(false);
					_parent->getMap()->cacheUnits();
				}
			}
//.........这里部分代码省略.........
开发者ID:mydmitry,项目名称:OpenXcom,代码行数:101,代码来源:ProjectileFlyBState.cpp

示例8: invMouseOver

/**
 * Shows item info.
 * @param action Pointer to an action.
 */
void InventoryState::invMouseOver(Action *)
{
	if (_inv->getSelectedItem() != 0)
	{
		return;
	}

	BattleItem *item = _inv->getMouseOverItem();
	if (item != 0)
	{
		if (item->getUnit() && item->getUnit()->getStatus() == STATUS_UNCONSCIOUS)
		{
			_txtItem->setText(item->getUnit()->getName(_game->getLanguage()));
		}
		else
		{
			if (_game->getSavedGame()->isResearched(item->getRules()->getRequirements()))
			{
				_txtItem->setText(tr(item->getRules()->getName()));
			}
			else
			{
				_txtItem->setText(tr("STR_ALIEN_ARTIFACT"));
			}
		}
		std::wstring s;
		if (item->getAmmoItem() != 0 && item->needsAmmo())
		{
			s = tr("STR_AMMO_ROUNDS_LEFT").arg(item->getAmmoItem()->getAmmoQuantity());
			SDL_Rect r;
			r.x = 0;
			r.y = 0;
			r.w = RuleInventory::HAND_W * RuleInventory::SLOT_W;
			r.h = RuleInventory::HAND_H * RuleInventory::SLOT_H;
			_selAmmo->drawRect(&r, _game->getMod()->getInterface("inventory")->getElement("grid")->color);
			r.x++;
			r.y++;
			r.w -= 2;
			r.h -= 2;
			_selAmmo->drawRect(&r, Palette::blockOffset(0)+15);
			item->getAmmoItem()->getRules()->drawHandSprite(_game->getMod()->getSurfaceSet("BIGOBS.PCK"), _selAmmo);
			_updateTemplateButtons(false);
		}
		else
		{
			_selAmmo->clear();
			_updateTemplateButtons(!_tu);
		}
		if (item->getAmmoQuantity() != 0 && item->needsAmmo())
		{
			s = tr("STR_AMMO_ROUNDS_LEFT").arg(item->getAmmoQuantity());
		}
		else if (item->getRules()->getBattleType() == BT_MEDIKIT)
		{
			s = tr("STR_MEDI_KIT_QUANTITIES_LEFT").arg(item->getPainKillerQuantity()).arg(item->getStimulantQuantity()).arg(item->getHealQuantity());
		}
		_txtAmmo->setText(s);
	}
	else
	{
		if (_currentTooltip.empty())
		{
			_txtItem->setText(L"");
		}
		_txtAmmo->setText(L"");
		_selAmmo->clear();
		_updateTemplateButtons(!_tu);
	}
}
开发者ID:Xracer,项目名称:OXCHD,代码行数:73,代码来源:InventoryState.cpp

示例9: btnApplyTemplateClick

void InventoryState::btnApplyTemplateClick(Action *)
{
	// don't accept clicks when moving items
	// it's ok if the template is empty -- it will just result in clearing the
	// unit's inventory
	if (_inv->getSelectedItem() != 0)
	{
		return;
	}

	BattleUnit               *unit          = _battleGame->getSelectedUnit();
	std::vector<BattleItem*> *unitInv       = unit->getInventory();
	Tile                     *groundTile    = unit->getTile();
	std::vector<BattleItem*> *groundInv     = groundTile->getInventory();
	RuleInventory            *groundRuleInv = _game->getMod()->getInventory("STR_GROUND");

	_clearInventory(_game, unitInv, groundTile);

	// attempt to replicate inventory template by grabbing corresponding items
	// from the ground.  if any item is not found on the ground, display warning
	// message, but continue attempting to fulfill the template as best we can
	bool itemMissing = false;
	std::vector<EquipmentLayoutItem*>::iterator templateIt;
	for (templateIt = _curInventoryTemplate.begin(); templateIt != _curInventoryTemplate.end(); ++templateIt)
	{
		// search for template item in ground inventory
		std::vector<BattleItem*>::iterator groundItem;
		const bool needsAmmo = !_game->getMod()->getItem((*templateIt)->getItemType())->getCompatibleAmmo()->empty();
		bool found = false;
		bool rescan = true;
		while (rescan)
		{
			rescan = false;

			const std::string targetAmmo = (*templateIt)->getAmmoItem();
			BattleItem *matchedWeapon = NULL;
			BattleItem *matchedAmmo   = NULL;
			for (groundItem = groundInv->begin(); groundItem != groundInv->end(); ++groundItem)
			{
				// if we find the appropriate ammo, remember it for later for if we find
				// the right weapon but with the wrong ammo
				const std::string groundItemName = (*groundItem)->getRules()->getType();
				if (needsAmmo && targetAmmo == groundItemName)
				{
					matchedAmmo = *groundItem;
				}

				if ((*templateIt)->getItemType() == groundItemName)
				{
					// if the loaded ammo doesn't match the template item's,
					// remember the weapon for later and continue scanning
					BattleItem *loadedAmmo = (*groundItem)->getAmmoItem();
					if ((needsAmmo && loadedAmmo && targetAmmo != loadedAmmo->getRules()->getType())
					 || (needsAmmo && !loadedAmmo))
					{
						// remember the last matched weapon for simplicity (but prefer empty weapons if any are found)
						if (!matchedWeapon || matchedWeapon->getAmmoItem())
						{
							matchedWeapon = *groundItem;
						}
						continue;
					}

					// move matched item from ground to the appropriate inv slot
					(*groundItem)->setOwner(unit);
					(*groundItem)->setSlot(_game->getMod()->getInventory((*templateIt)->getSlot()));
					(*groundItem)->setSlotX((*templateIt)->getSlotX());
					(*groundItem)->setSlotY((*templateIt)->getSlotY());
					(*groundItem)->setFuseTimer((*templateIt)->getFuseTimer());
					unitInv->push_back(*groundItem);
					groundInv->erase(groundItem);
					found = true;
					break;
				}
			}

			// if we failed to find an exact match, but found unloaded ammo and
			// the right weapon, unload the target weapon, load the right ammo, and use it
			if (!found && matchedWeapon && (!needsAmmo || matchedAmmo))
			{
				// unload the existing ammo (if any) from the weapon
				BattleItem *loadedAmmo = matchedWeapon->getAmmoItem();
				if (loadedAmmo)
				{
					groundTile->addItem(loadedAmmo, groundRuleInv);
					matchedWeapon->setAmmoItem(NULL);
				}

				// load the correct ammo into the weapon
				if (matchedAmmo)
				{
					matchedWeapon->setAmmoItem(matchedAmmo);
					groundTile->removeItem(matchedAmmo);
				}

				// rescan and pick up the newly-loaded/unloaded weapon
				rescan = true;
			}
		}

//.........这里部分代码省略.........
开发者ID:Xracer,项目名称:OXCHD,代码行数:101,代码来源:InventoryState.cpp

示例10: think

/**
 * Runs any code the state needs to keep updating every
 * AI cycle.
 * @param action (possible) AI action to execute after thinking is done.
 */
void AggroBAIState::think(BattleAction *action)
{
	action->type = BA_RETHINK;
	action->actor = _unit;
	/* Aggro is mainly either shooting a target or running towards it (melee).
	   If we do no action here - we assume we lost aggro and will go back to patrol state.
	*/
	int aggression = _unit->getAggression();
	_aggroTarget = 0;
	int unitsSpottingMe = _game->getSpottingUnits(_unit);


	/*	psionic targetting: pick from any of the "exposed" units.
		exposed means they have been previously spotted, and are therefore "known" to the AI,
		regardless of whether we can see them or not, because we're psychic.
	*/
	if (_unit->getStats()->psiSkill && _unit->getType() != "SOLDIER" && _game->getExposedUnits()->size() > 0 && RNG::generate(0, 100) > 66)
	{
		int psiAttackStrength = _unit->getStats()->psiSkill * _unit->getStats()->psiStrength / 50;
		int chanceToAttack = 0;
		int tries = 0;
		for (std::vector<BattleUnit*>::const_iterator i = _game->getExposedUnits()->begin(); i != _game->getExposedUnits()->end() && tries < 80; ++i)
		{
			// don't target tanks
			if ((*i)->getArmor()->getSize() != 2)
			{
				int chanceToAttackMe = psiAttackStrength
					+ ((*i)->getStats()->psiSkill * -0.4)
					- (_game->getTileEngine()->distance(_unit->getPosition(), (*i)->getPosition()) / 2)
					- ((*i)->getStats()->psiStrength)
					+ (RNG::generate(0, 50))
					+ 55;

				if (chanceToAttackMe > chanceToAttack)
				{
					chanceToAttack = chanceToAttackMe;
					_aggroTarget = *i;
				}
			}
			++tries;
		}

		if (!_aggroTarget)
			chanceToAttack = 0;

		if (chanceToAttack)
		{
			if (_unit->getMainHandWeapon() && _unit->getMainHandWeapon()->getAmmoItem())
			{
				if (_unit->getMainHandWeapon()->getAmmoItem()->getRules()->getPower() >= chanceToAttack)
				{
					chanceToAttack = 0;
					_aggroTarget = 0;
				}
			}
			else
			{
				if (RNG::generate(35, 155) >= chanceToAttack)
				{
					chanceToAttack = 0;
					_aggroTarget = 0;
				}
			}
			if (chanceToAttack >= 30)
			{
				int controlOrPanic = 60;
				int morale = _aggroTarget->getMorale();
				int bravery = _aggroTarget->getStats()->bravery;
				if (bravery > 60)
					controlOrPanic += 15;
				if ( bravery < 40)
					controlOrPanic -= 15;
				if (morale >= 40)
				{
					if (morale - 10 * bravery < 50)
						controlOrPanic += 15;
				}
				else
				{
					controlOrPanic -= 15;
				}
				if (!morale)
				{
					controlOrPanic = 0;
				}
				if (RNG::generate(0, 100) >= controlOrPanic)
				{
					action->type = BA_MINDCONTROL;
					action->target = _aggroTarget->getPosition();
				}
				else
				{
					action->type = BA_PANIC;
					action->target = _aggroTarget->getPosition();
				}
//.........这里部分代码省略.........
开发者ID:iThompson,项目名称:OpenXcom,代码行数:101,代码来源:AggroBAIState.cpp

示例11: think

/**
 * Runs any code the state needs to keep updating every
 * AI cycle.
 * @param action (possible) AI action to execute after thinking is done.
 */
void AggroBAIState::think(BattleAction *action)
{
	if (Options::getBool("traceAI")) { Log(LOG_INFO) << "AggroBAIState::think() #" << action->number << (charge ? " [charging]": " "); }
	
 	action->type = BA_RETHINK;
	action->actor = _unit;
	/* Aggro is mainly either shooting a target or running towards it (melee).
	   If we do no action here - we assume we lost aggro and will go back to patrol state.
	*/
	int aggression = _unit->getAggression();
	if (!charge || (_aggroTarget && (_aggroTarget->isOut() || _aggroTarget->getFaction() == _unit->getFaction()))) 
	{
		_aggroTarget = 0;
	} else
	{
		action->type = BA_WALK; // just in case
		action->target = _lastKnownPosition;
	}
	int unitsSpottingMe = _game->getSpottingUnits(_unit);


	/*	psionic targetting: pick from any of the "exposed" units.
		exposed means they have been previously spotted, and are therefore "known" to the AI,
		regardless of whether we can see them or not, because we're psychic.
	*/
	if (_unit->getStats()->psiSkill && _unit->getType() != "SOLDIER" && _game->getExposedUnits()->size() > 0 && RNG::generate(0, 100) > 66)
	{
		int psiAttackStrength = _unit->getStats()->psiSkill * _unit->getStats()->psiStrength / 50;
		int chanceToAttack = 0;
		int tries = 0;
		for (std::vector<BattleUnit*>::const_iterator i = _game->getExposedUnits()->begin(); i != _game->getExposedUnits()->end() && tries < 80; ++i)
		{
			// don't target tanks
			if ((*i)->getArmor()->getSize() != 2)
			{
				int chanceToAttackMe = psiAttackStrength
					+ ((*i)->getStats()->psiSkill * -0.4)
					- (_game->getTileEngine()->distance(_unit->getPosition(), (*i)->getPosition()) / 2)
					- ((*i)->getStats()->psiStrength)
					+ (RNG::generate(0, 50))
					+ 55;

				if (chanceToAttackMe > chanceToAttack)
				{
					chanceToAttack = chanceToAttackMe;
					_aggroTarget = *i;
				}
			}
			++tries;
		}

		if (!_aggroTarget)
			chanceToAttack = 0;

		if (chanceToAttack)
		{
			if (_unit->getMainHandWeapon() && _unit->getMainHandWeapon()->getAmmoItem())
			{
				if (_unit->getMainHandWeapon()->getAmmoItem()->getRules()->getPower() >= chanceToAttack)
				{
					chanceToAttack = 0;
					_aggroTarget = 0;
				}
			}
			else
			{
				if (RNG::generate(35, 155) >= chanceToAttack)
				{
					chanceToAttack = 0;
					_aggroTarget = 0;
				}
			}
			if (chanceToAttack >= 30)
			{
				int controlOrPanic = 60;
				int morale = _aggroTarget->getMorale();
				int bravery = _aggroTarget->getStats()->bravery;
				if (bravery > 60)
					controlOrPanic += 15;
				if ( bravery < 40)
					controlOrPanic -= 15;
				if (morale >= 40)
				{
					if (morale - 10 * bravery < 50)
						controlOrPanic += 15;
				}
				else
				{
					controlOrPanic -= 15;
				}
				if (!morale)
				{
					controlOrPanic = 0;
				}
				if (RNG::generate(0, 100) >= controlOrPanic)
//.........这里部分代码省略.........
开发者ID:hmaon,项目名称:OpenXcom,代码行数:101,代码来源:AggroBAIState.cpp

示例12: init

/**
 * init sequence:
 * - check if shot is valid
 * - calculate base accuracy
 */
void ProjectileFlyBState::init()
{
	if (_initialized) return;
	_initialized = true;

	BattleItem *weapon = _action.weapon;
	_projectileItem = 0;
	_autoshotCounter = 0;
	
	if (!weapon) // can't shoot without weapon
		return;

	if (_action.actor->getTimeUnits() < _action.TU && !_parent->dontSpendTUs())
	{
		_result = "STR_NOT_ENOUGH_TIME_UNITS";
		_parent->popState();
		return;
	}

	_unit = _action.actor;
	_ammo = weapon->getAmmoItem();
	if (_unit->isOut())
	{
		// something went wrong
		_parent->popState();
		return;
	}
	if (_action.type != BA_THROW)
	{
		if (_ammo == 0)
		{
			_result = "STR_NO_AMMUNITION_LOADED";
			_parent->popState();
			return;
		}
		if (_ammo->getAmmoQuantity() == 0)
		{
			_result = "STR_NO_ROUNDS_LEFT";
			_parent->popState();
			return;
		}
	}
	// action specific initialisation
	switch (_action.type)
	{
	case BA_AUTOSHOT:
		_baseAcc = weapon->getRules()->getAccuracyAuto();
		break;
	case BA_SNAPSHOT:
		_baseAcc = weapon->getRules()->getAccuracySnap();
		break;
	case BA_AIMEDSHOT:
		_baseAcc = weapon->getRules()->getAccuracyAimed();
		break;
	case BA_THROW:
		if (!validThrowRange())
		{
			// out of range
			_result = "STR_OUT_OF_RANGE";
			_parent->popState();
			return;
		}
		_baseAcc = (int)(_unit->getThrowingAccuracy()*100.0);
		_projectileItem = weapon;
		break;
    default:
        _baseAcc = 0;
	}

	createNewProjectile();

	BattleAction action;
	BattleUnit *potentialVictim = _parent->getGame()->getSavedGame()->getBattleGame()->getTile(_action.target)->getUnit();
	if (potentialVictim && potentialVictim->getFaction() != _unit->getFaction())
	{
		if (_parent->getGame()->getSavedGame()->getBattleGame()->getTileEngine()->checkReactionFire(_unit, &action, potentialVictim, false))
		{
			_parent->statePushBack(new ProjectileFlyBState(_parent, action));
		}
	}
}
开发者ID:ben0x539,项目名称:OpenXcom,代码行数:86,代码来源:ProjectileFlyBState.cpp

示例13: think

/**
 * Animates the projectile (move to the next point in it's trajectory).
 * If the animation is finished the projectile sprite is removed from the map.
 * And this state is finished.
 */
void ProjectileFlyBState::think()
{
	if (_parent->getMap()->getProjectile() == 0)
	{
		if (_action.type == BA_AUTOSHOT && _autoshotCounter < 3 && !_action.actor->isOut())
		{
			createNewProjectile();
		}
		else
		{
			_parent->popState();
		}
	}
	else
	{
		if(!_parent->getMap()->getProjectile()->move())
		{
			// impact !
			if (_action.type == BA_THROW)
			{
				Position pos = _parent->getMap()->getProjectile()->getPosition(-1);
				pos.x /= 16;
				pos.y /= 16;
				pos.z /= 24;
				BattleItem *item = _parent->getMap()->getProjectile()->getItem();
				_parent->getGame()->getResourcePack()->getSoundSet("BATTLE.CAT")->getSound(38)->play();

				if (Options::getBool("battleAltGrenade") && item->getRules()->getBattleType() == BT_GRENADE)
				{
					// it's a hot grenade to explode immediatly
					_parent->statePushFront(new ExplosionBState(_parent, _parent->getMap()->getProjectile()->getPosition(-1), item, _action.actor));
				}
				else
				{
					_parent->dropItem(pos, item);
				}
			}
			else
			{
				if (_projectileImpact != 5) // out of map
				{
					int offset = 0;
					// explosions impact not inside the voxel but one step back
					if (_ammo && (
						_ammo->getRules()->getDamageType() == DT_HE ||
						_ammo->getRules()->getDamageType() == DT_IN))
					{
						offset = -1;
					}
					_parent->statePushFront(new ExplosionBState(_parent, _parent->getMap()->getProjectile()->getPosition(offset), _ammo, _action.actor));
				}
				else
				{
					_unit->aim(false);
					_parent->getMap()->cacheUnits();
					if (_parent->getMap()->didCameraFollow() && _parent->getGame()->getSavedGame()->getBattleGame()->getSide() == FACTION_PLAYER)
					{
						_parent->getMap()->centerOnPosition(_parent->getGame()->getSavedGame()->getBattleGame()->getSelectedUnit()->getPosition());
					}
				}
			}

			delete _parent->getMap()->getProjectile();
			_parent->getMap()->setProjectile(0);
		}
	}
}
开发者ID:ben0x539,项目名称:OpenXcom,代码行数:72,代码来源:ProjectileFlyBState.cpp

示例14: init

/**
 * Initializes the explosion.
 * The animation and sound starts here.
 * If the animation is finished, the actual effect takes place.
 */
void ExplosionBState::init()
{
	BattleType type = BT_NONE;
	BattleActionType action = _action.type;
	const RuleItem* itemRule = 0;
	bool miss = false;
	if (_item)
	{
		itemRule = _item->getRules();
		type = itemRule->getBattleType();

		_power = 0;
		_pistolWhip = (type != BT_MELEE && action == BA_HIT);
		if (_pistolWhip)
		{
			_power += itemRule->getMeleeBonus(_unit);

			_radius = 0;
			_damageType = itemRule->getMeleeType();
		}
		else
		{
			_power += itemRule->getPowerBonus(_unit);
			_power -= itemRule->getPowerRangeReduction(_range);

			_radius = itemRule->getExplosionRadius(_unit);
			_damageType = itemRule->getDamageType();
		}

		//testing if we hit target
		if (type == BT_PSIAMP && !_pistolWhip)
		{
			if (action != BA_USE)
			{
				_power = 0;
			}
			if (!_parent->psiAttack(&_action))
			{
				_power = 0;
				miss = true;
			}
		}
		else if (type == BT_MELEE || _pistolWhip)
		{
			if (!_parent->getTileEngine()->meleeAttack(&_action))
			{
				_power = 0;
				miss = true;
			}
		}
		else if (type == BT_FIREARM)
		{
			if (_power <= 0)
			{
				miss = true;
			}
		}

		_areaOfEffect = type != BT_MELEE && _radius != 0 &&
						(type != BT_PSIAMP || action == BA_USE) &&
						!_pistolWhip && !miss;
	}
	else if (_tile)
	{
		ItemDamageType DT;
		switch (_tile->getExplosiveType())
		{
		case 0:
			DT = DT_HE;
			break;
		case 5:
			DT = DT_IN;
			break;
		case 6:
			DT = DT_STUN;
			break;
		default:
			DT = DT_SMOKE;
			break;
		}
		_power = _tile->getExplosive();
		_tile->setExplosive(0, 0, true);
		_damageType = _parent->getMod()->getDamageType(DT);
		_radius = _power /10;
		_areaOfEffect = true;
	}
	else if (_unit && (_unit->getSpecialAbility() == SPECAB_EXPLODEONDEATH || _unit->getSpecialAbility() == SPECAB_BURN_AND_EXPLODE))
	{
		RuleItem* corpse = _parent->getMod()->getItem(_unit->getArmor()->getCorpseGeoscape());
		_power = corpse->getPowerBonus(_unit);
		_damageType = corpse->getDamageType();
		_radius = corpse->getExplosionRadius(_unit);
		_areaOfEffect = true;
		if (!RNG::percent(corpse->getSpecialChance()))
		{
//.........这里部分代码省略.........
开发者ID:Stalkstalks,项目名称:OpenXcom,代码行数:101,代码来源:ExplosionBState.cpp

示例15: explode

/**
 * Calculates the effects of the explosion.
 */
void ExplosionBState::explode()
{
	bool terrainExplosion = false;
	SavedBattleGame *save = _parent->getSave();
	// last minute adjustment: determine if we actually
	if (_hit)
	{
		if (_unit && !_unit->isOut())
		{
			_unit->aim(false);
		}

		if (_power <= 0)
		{
			_parent->popState();
			return;
		}

		int sound = _item->getRules()->getMeleeHitSound();
		if (!_pistolWhip)
		{
			// melee weapon with ammo
			BattleItem *ammo = _item->getAmmoItem();
			if (ammo)
			{
				optValue(sound, ammo->getRules()->getMeleeHitSound());
			}
		}
		_parent->playSound(sound, _action.target);
	}
	// after the animation is done, the real explosion/hit takes place
	if (_item)
	{
		if (!_unit && _item->getPreviousOwner())
		{
			_unit = _item->getPreviousOwner();
		}
	}

	bool range = !(_hit || (_item && _item->getRules()->getBattleType() == BT_PSIAMP));

	if (_areaOfEffect)
	{
		save->getTileEngine()->explode(_center, _power, _damageType, _radius, _unit, _item, range);
	}
	else
	{
		BattleUnit *victim = save->getTileEngine()->hit(_center, _power, _damageType, _unit, _item, range);
		// check if this unit turns others into zombies
		if (!_item->getRules()->getZombieUnit().empty()
			&& RNG::percent(_item->getRules()->getSpecialChance())
			&& victim
			&& victim->getArmor()->getZombiImmune() == false
			&& victim->getSpawnUnit().empty()
			&& victim->getOriginalFaction() != FACTION_HOSTILE)
		{
			// converts the victim to a zombie on death
			victim->setRespawn(true);
			victim->setSpawnUnit(_item->getRules()->getZombieUnit());
		}
	}

	if (_tile)
	{
		terrainExplosion = true;
	}
	if (!_tile && !_item)
	{
		terrainExplosion = true;
	}

	// now check for new casualties
	_parent->checkForCasualties(_item ? _damageType : 0, _item, _unit, false, terrainExplosion);
	// revive units if damage could give hp or reduce stun
	_parent->getSave()->reviveUnconsciousUnits(true);

	// if this explosion was caused by a unit shooting, now it's the time to put the gun down
	if (_unit && !_unit->isOut() && _lowerWeapon)
	{
		_unit->aim(false);
	}

	if (_item && (_item->getRules()->getBattleType() == BT_GRENADE || _item->getRules()->getBattleType() == BT_PROXIMITYGRENADE))
	{
		_parent->getSave()->removeItem(_item);
	}

	_parent->popState();

	// check for terrain explosions
	Tile *t = save->getTileEngine()->checkForTerrainExplosions();
	if (t)
	{
		Position p = t->getPosition().toVexel();
		p += Position(8,8,0);
		_parent->statePushFront(new ExplosionBState(_parent, p, BA_NONE, 0, _unit, t));
	}
//.........这里部分代码省略.........
开发者ID:Stalkstalks,项目名称:OpenXcom,代码行数:101,代码来源:ExplosionBState.cpp


注:本文中的BattleItem::getRules方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。