本文整理汇总了C++中BattleItem类的典型用法代码示例。如果您正苦于以下问题:C++ BattleItem类的具体用法?C++ BattleItem怎么用?C++ BattleItem使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了BattleItem类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: BattleItem
/*
* Convert unit to corpse(item).
*/
void UnitDieBState::convertUnitToCorpse()
{
// in case the unit was unconscious
_parent->getSave()->removeUnconsciousBodyItem(_unit);
int size = _unit->getArmor()->getSize() - 1;
// move inventory from unit to the ground for non-large units
if (size == 0)
{
for (std::vector<BattleItem*>::iterator i = _unit->getInventory()->begin(); i != _unit->getInventory()->end(); ++i)
{
_parent->dropItem(_unit->getPosition(), (*i));
}
}
_unit->getInventory()->clear();
// remove unit-tile link
_unit->setTile(0);
if (size == 0)
{
BattleItem *corpse = new BattleItem(_parent->getRuleset()->getItem(_unit->getArmor()->getCorpseItem()),_parent->getSave()->getCurrentItemId());
corpse->setUnit(_unit);
_parent->dropItem(_unit->getPosition(), corpse, true);
_parent->getSave()->getTile(_unit->getPosition())->setUnit(0);
}
else
{
Position p = _unit->getPosition();
int i = 1;
for (int y = 0; y <= size; y++)
{
for (int x = 0; x <= size; x++)
{
std::stringstream ss;
ss << _unit->getArmor()->getCorpseItem() << i;
BattleItem *corpse = new BattleItem(_parent->getRuleset()->getItem(ss.str()),_parent->getSave()->getCurrentItemId());
corpse->setUnit(_unit); // no need for this, because large units never can be revived as they don't go unconscious
// yes there freaking is because yes they freaking do, nerf their consciousness elswhere,
// because we need to recover live reapers and i need this kept track of for corpse recovery. also i hate reapers.
_parent->dropItem(p + Position(x,y,0), corpse, true);
_parent->getSave()->getTile(p + Position(x,y,0))->setUnit(0);
i++;
}
}
}
}
示例2: BattleItem
/*
* Convert unit to corpse(item).
* @param unit
* @param terrain
*/
void UnitDieBState::convertUnitToCorpse(BattleUnit *unit, TileEngine *terrain)
{
int size = _unit->getUnit()->getArmor()->getSize() - 1;
// move inventory from unit to the ground for non-large units
if (size == 0)
{
for (std::vector<BattleItem*>::iterator i = _unit->getInventory()->begin(); i != _unit->getInventory()->end(); ++i)
{
_parent->dropItem(_unit->getPosition(), (*i));
}
}
_unit->getInventory()->clear();
// remove unit-tile link
_unit->setTile(0);
if (size == 0)
{
_parent->getGame()->getSavedGame()->getBattleGame()->getTile(_unit->getPosition())->setUnit(0);
BattleItem *corpse = new BattleItem(_parent->getGame()->getRuleset()->getItem(_unit->getUnit()->getArmor()->getCorpseItem()),_parent->getGame()->getSavedGame()->getBattleGame()->getCurrentItemId());
corpse->setUnit(unit);
_parent->dropItem(_unit->getPosition(), corpse, true);
}
else
{
int i = 1;
for (int y = 0; y <= size; y++)
{
for (int x = 0; x <= size; x++)
{
_parent->getGame()->getSavedGame()->getBattleGame()->getTile(_unit->getPosition() + Position(x,y,0))->setUnit(0);
std::stringstream ss;
ss << _unit->getUnit()->getArmor()->getCorpseItem() << i;
BattleItem *corpse = new BattleItem(_parent->getGame()->getRuleset()->getItem(ss.str()),_parent->getGame()->getSavedGame()->getBattleGame()->getCurrentItemId());
//corpse->setUnit(unit); // no need for this, because large units never can be revived as they don't go unconscious
_parent->dropItem(_unit->getPosition() + Position(x,y,0), corpse, true);
i++;
}
}
}
}
示例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;
}
}
示例4: 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)
{
_txtItem->setText(_game->getLanguage()->getString(item->getRules()->getType()));
std::wstringstream ss;
if (item->getAmmoItem() != 0)
{
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)
{
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());
}
}
示例5: 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));
//.........这里部分代码省略.........
示例6: BattleItem
/**
* Converts unit to a corpse (item).
*/
void UnitDieBState::convertUnitToCorpse()
{
_parent->getSave()->getBattleState()->showPsiButton(false);
Position lastPosition = _unit->getPosition();
// remove the unconscious body item corresponding to this unit, and if it was being carried, keep track of what slot it was in
if (lastPosition != Position(-1,-1,-1))
{
_parent->getSave()->removeUnconsciousBodyItem(_unit);
}
int size = _unit->getArmor()->getSize();
BattleItem *itemToKeep = 0;
bool dropItems = !Options::weaponSelfDestruction || (_unit->getOriginalFaction() != FACTION_HOSTILE || _unit->getStatus() == STATUS_UNCONSCIOUS);
// move inventory from unit to the ground for non-large units
if (size == 1 && dropItems)
{
for (std::vector<BattleItem*>::iterator i = _unit->getInventory()->begin(); i != _unit->getInventory()->end(); ++i)
{
_parent->dropItem(lastPosition, (*i));
if (!(*i)->getRules()->isFixed())
{
(*i)->setOwner(0);
}
else
{
itemToKeep = *i;
}
}
}
_unit->getInventory()->clear();
if (itemToKeep != 0)
{
_unit->getInventory()->push_back(itemToKeep);
}
// remove unit-tile link
_unit->setTile(0);
if (lastPosition == Position(-1,-1,-1)) // we're being carried
{
// replace the unconscious body item with a corpse in the carrying unit's inventory
for (std::vector<BattleItem*>::iterator it = _parent->getSave()->getItems()->begin(); it != _parent->getSave()->getItems()->end(); )
{
if ((*it)->getUnit() == _unit)
{
RuleItem *corpseRules = _parent->getRuleset()->getItem(_unit->getArmor()->getCorpseBattlescape()[0]); // we're in an inventory, so we must be a 1x1 unit
(*it)->convertToCorpse(corpseRules);
break;
}
++it;
}
}
else
{
int i = 0;
for (int y = 0; y < size; y++)
{
for (int x = 0; x < size; x++)
{
BattleItem *corpse = new BattleItem(_parent->getRuleset()->getItem(_unit->getArmor()->getCorpseBattlescape()[i]), _parent->getSave()->getCurrentItemId());
corpse->setUnit(_unit);
if (_parent->getSave()->getTile(lastPosition + Position(x,y,0))->getUnit() == _unit) // check in case unit was displaced by another unit
{
_parent->getSave()->getTile(lastPosition + Position(x,y,0))->setUnit(0);
}
_parent->dropItem(lastPosition + Position(x,y,0), corpse, true);
i++;
}
}
}
}
示例7: createNewProjectile
/**
* 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);
}
}
}
示例8: createNewProjectile
/**
* 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();
}
}
//.........这里部分代码省略.........
示例9: 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;
}
//.........这里部分代码省略.........
示例10: drawItemSprite
/**
* Updates soldier name/rank/tu/energy/health/morale.
* @param battleUnit Pointer to current unit.
*/
void BattlescapeState::updateSoldierInfo(BattleUnit *battleUnit)
{
if (battleUnit == 0)
{
_txtName->setText(L"");
_rank->clear();
_numTimeUnits->clear();
_barTimeUnits->clear();
_barTimeUnits->clear();
_numEnergy->clear();
_barEnergy->clear();
_barEnergy->clear();
_numHealth->clear();
_barHealth->clear();
_barHealth->clear();
_numMorale->clear();
_barMorale->clear();
_barMorale->clear();
_btnLeftHandItem->clear();
_btnRightHandItem->clear();
return;
}
_txtName->setText(battleUnit->getUnit()->getName());
Soldier *soldier = dynamic_cast<Soldier*>(battleUnit->getUnit());
if (soldier != 0)
{
SurfaceSet *texture = _game->getResourcePack()->getSurfaceSet("BASEBITS.PCK");
texture->getFrame(soldier->getRankSprite())->blit(_rank);
}
_numTimeUnits->setValue(battleUnit->getTimeUnits());
_barTimeUnits->setMax(battleUnit->getUnit()->getTimeUnits());
_barTimeUnits->setValue(battleUnit->getTimeUnits());
_numEnergy->setValue(battleUnit->getEnergy());
_barEnergy->setMax(battleUnit->getUnit()->getStamina());
_barEnergy->setValue(battleUnit->getEnergy());
_numHealth->setValue(battleUnit->getHealth());
_barHealth->setMax(battleUnit->getUnit()->getHealth());
_barHealth->setValue(battleUnit->getHealth());
_numMorale->setValue(battleUnit->getMorale());
_barMorale->setMax(100);
_barMorale->setValue(battleUnit->getMorale());
BattleItem *leftHandItem = _battleGame->getItemFromUnit(battleUnit, LEFT_HAND);
_btnLeftHandItem->clear();
_numAmmoLeft->clear();
if (leftHandItem)
{
drawItemSprite(leftHandItem, _btnLeftHandItem);
_numAmmoLeft->setValue(leftHandItem->getAmmoQuantity());
}
BattleItem *rightHandItem = _battleGame->getItemFromUnit(battleUnit, RIGHT_HAND);
_btnRightHandItem->clear();
_numAmmoRight->clear();
if (rightHandItem)
{
drawItemSprite(rightHandItem, _btnRightHandItem);
_numAmmoRight->setValue(rightHandItem->getAmmoQuantity());
}
_battleGame->getTerrainModifier()->calculateFOV(_battleGame->getSelectedUnit());
for (int i = 0; i < 10; i++)
{
_btnVisibleUnit[i]->hide();
_numVisibleUnit[i]->hide();
_visibleUnit[i] = 0;
}
int j = 0;
for (std::vector<BattleUnit*>::iterator i = battleUnit->getVisibleUnits()->begin(); i != battleUnit->getVisibleUnits()->end(); i++)
{
_btnVisibleUnit[j]->show();
_numVisibleUnit[j]->show();
_visibleUnit[j] = (*i);
j++;
}
}
示例11: if
//.........这里部分代码省略.........
Position p = _center;
p.x += X; p.y += Y;
Explosion *explosion = new Explosion(p, frame, frameDelay, true);
// add the explosion on the map
_parent->getMap()->getExplosions()->push_back(explosion);
if (i > 0 && i % counter == 0)
{
frameDelay++;
}
}
_parent->setStateInterval(BattlescapeState::DEFAULT_ANIM_SPEED/2);
// explosion sound
int sound = _power <= 80 ? Mod::SMALL_EXPLOSION : Mod::LARGE_EXPLOSION;
if (_item) optValue(sound, itemRule->getExplosionHitSound());
_parent->playSound(sound);
_parent->getMap()->getCamera()->centerOnPosition(t->getPosition(), false);
}
else
{
_parent->popState();
}
}
else
// create a bullet hit
{
_parent->setStateInterval(std::max(1, ((BattlescapeState::DEFAULT_ANIM_SPEED/2) - (10 * itemRule->getExplosionSpeed()))));
_hit = _pistolWhip || type == BT_MELEE;
bool psi = type == BT_PSIAMP && action != BA_USE && !_pistolWhip;
int anim = -1;
int sound = -1;
// melee weapon with ammo
BattleItem *ammo = !_pistolWhip && _hit ? _item->getAmmoItem() : 0;
if (_hit || psi)
{
anim = itemRule->getMeleeAnimation();
if (psi)
{
// psi attack sound is based weapon hit sound
sound = itemRule->getHitSound();
optValue(anim, itemRule->getPsiAnimation());
optValue(sound, itemRule->getPsiSound());
}
else
{
sound = itemRule->getMeleeSound();
if (ammo)
{
optValue(anim, ammo->getRules()->getMeleeAnimation());
optValue(sound, ammo->getRules()->getMeleeSound());
}
}
}
else
{
anim = itemRule->getHitAnimation();
sound = itemRule->getHitSound();
}
if (miss)
{
if (_hit || psi)
{
示例12: 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));
}
//.........这里部分代码省略.........
示例13: _clearInventory
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;
}
}
//.........这里部分代码省略.........
示例14: MapDataSet
//.........这里部分代码省略.........
(*i)["position"][1] >> pos.y;
(*i)["position"][2] >> pos.z;
getTile(pos)->load((*i));
}
for (YAML::Iterator i = node["nodes"].begin(); i != node["nodes"].end(); ++i)
{
Node *n = new Node();
n->load(*i);
_nodes.push_back(n);
}
for (YAML::Iterator i = node["units"].begin(); i != node["units"].end(); ++i)
{
UnitFaction faction;
(*i)["faction"] >> a;
faction = (UnitFaction)a;
(*i)["soldierId"] >> a;
Unit *unit;
if (a != -1) // Unit is linked to a geoscape soldier
{
// look up the matching soldier
unit = savedGame->getSoldier(a);
}
else
{
// create a new Unit.
unit = new GenUnit(rule->getGenUnit("SECTOID_SOLDIER"), rule->getArmor("SECTOID_ARMOR0"));
}
BattleUnit *b = new BattleUnit(unit, faction);
b->load(*i);
_units.push_back(b);
if (faction == FACTION_PLAYER)
{
if (b->getId() == selectedUnit)
_selectedUnit = b;
}
else
{
std::string state;
BattleAIState *aiState;
(*i)["AI"]["state"] >> state;
if (state == "PATROL")
{
aiState = new PatrolBAIState(this, b, 0);
}
else if (state == "AGGRO")
{
aiState = new AggroBAIState(this, b);
}
else
{
continue;
}
aiState->load((*i)["AI"]);
b->setAIState(aiState);
}
}
// matches up tiles and units
resetUnitTiles();
for (YAML::Iterator i = node["items"].begin(); i != node["items"].end(); ++i)
{
std::string type;
(*i)["type"] >> type;
if (type != "0")
{
BattleItem *item = new BattleItem(rule->getItem(type), &_itemId);
item->load(*i);
(*i)["inventoryslot"] >> type;
if (type != "NULL")
item->setSlot(rule->getInventory(type));
(*i)["owner"] >> a;
// match up items and units
for (std::vector<BattleUnit*>::iterator bu = _units.begin(); bu != _units.end(); ++bu)
{
if ((*bu)->getId() == a)
{
item->moveToOwner(*bu);
break;
}
}
// match up items and tiles
if (item->getSlot() && item->getSlot()->getType() == INV_GROUND)
{
Position pos;
(*i)["position"][0] >> pos.x;
(*i)["position"][1] >> pos.y;
(*i)["position"][2] >> pos.z;
if (pos.x != -1)
getTile(pos)->addItem(item);
}
_items.push_back(item);
}
示例15: createNewProjectile
/**
* 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);
}
}
}