void JetPack::StartShooting() { if (active) { Deselect(); if (EnoughAmmo()) Select(); } else { if (EnoughAmmo()) { UseAmmo(); Game::GetInstance()->SetCharacterChosen(true); active = true; ActiveCharacter().SetClothe("jetpack-fire"); } } }
void Construct::ChooseTarget(Point2i mouse_pos) { if (!EnoughAmmo()) return; dst = mouse_pos; // Draw it so that GetSizeMax() returns the correct values. construct_spr->SetRotation_rad(angle); construct_spr->Draw(dst - construct_spr->GetSize() / 2); Point2i test_target = dst - construct_spr->GetSizeMax() / 2; Rectanglei rect(test_target, construct_spr->GetSizeMax()); if (!GetWorld().ParanoiacRectIsInVacuum(rect)) return; // Check collision with characters and other physical objects FOR_ALL_CHARACTERS(team, c) { if (c->GetTestRect().Intersect(rect)) return; } FOR_ALL_OBJECTS(it) { PhysicalObj *obj = *it; if (obj->GetTestRect().Intersect(rect)) return; } target_chosen = true; Shoot(); }
void Blowtorch::StartShooting() { if (active) { active = false; ActiveTeam().AccessNbUnits() = 0; } else { if (EnoughAmmo()) active = true; } }
void Airhammer::StartShooting() { if (!EnoughAmmo()) return; //if the sound isn't already playing, play it again. select_sound.Stop(); if (!drill_sound.IsPlaying()) { drill_sound.Play("default","weapon/airhammer", -1); } active = true; deactivation_requested = false; }
void Blowtorch::Refresh() { if (active) { const LRMoveIntention * lr_move_intention = ActiveCharacter().GetLastLRMoveIntention(); if (lr_move_intention && EnoughAmmoUnit()) { Weapon::RepeatShoot(); } } if (!EnoughAmmoUnit()) { active = false; if (EnoughAmmo()) { ActiveTeam().ResetNbUnits(); } } }
bool Weapon::Shoot() { MSG_DEBUG("weapon.shoot", "Enough ammo ? %d", EnoughAmmo()); MSG_DEBUG("weapon.shoot", "Enough ammo unit ? %d", EnoughAmmoUnit()); MSG_DEBUG("weapon.shoot", "Use unit on 1st shoot ? %d", use_unit_on_first_shoot); if (!IsReady()) return false; MSG_DEBUG("weapon.shoot", "Enough ammo"); #ifdef DEBUG Point2i hand; ActiveCharacter().GetHandPosition(hand); MSG_DEBUG("weapon.shoot", "%s Shooting at position:%d,%d (hand: %d,%d)", ActiveCharacter().GetName().c_str(), ActiveCharacter().GetX(), ActiveCharacter().GetY(), hand.GetX(), hand.GetY()); ActiveCharacter().body->DebugState(); #endif if (!p_Shoot()) { MSG_DEBUG("weapon.shoot", "shoot has failed!!"); return false; } m_last_fire_time = Time::GetInstance()->Read(); MSG_DEBUG("weapon.shoot", "shoot!"); // Is this the first shoot for this ammo use ? if (ActiveTeam().ReadNbUnits() == m_initial_nb_unit_per_ammo) { UseAmmo(); } if (use_unit_on_first_shoot){ UseAmmoUnit(); } if (max_strength.IsNotZero()) ActiveCharacter().previous_strength = m_strength; Game::GetInstance()->SetCharacterChosen(true); return true; }
bool Weapon::IsReady() const { // WARNING: The following commented code is wrong! Please see explanation following // if (!EnoughAmmo() // || (use_unit_on_first_shoot && !EnoughAmmoUnit())) // return false; // Gentildemon : YES the following code seems strange! // BUT when have only one ammo left, you shoot, then nb_ammo == 0 // then you need to be able to use the left ammo units if (use_unit_on_first_shoot && !EnoughAmmoUnit()) return false; if (!EnoughAmmo()) if (!(ActiveTeam().ReadNbAmmos() == 0 && use_unit_on_first_shoot && EnoughAmmoUnit())) return false; return true; }
void Construct::Draw() { Weapon::Draw(); if (EnoughAmmo() && EnoughAmmoUnit() && !Interface::GetInstance()->weapons_menu.IsDisplayed() && Interface::GetInstance()->IsDisplayed() && Network::GetInstance()->IsTurnMaster()) { dst = Mouse::GetInstance()->GetWorldPosition(); construct_spr->SetRotation_rad(angle); construct_spr->Draw(dst - construct_spr->GetSize() / 2); #ifdef DEBUG if (IsLOGGING("test_rectangle")) { Rectanglei test_rect(dst - construct_spr->GetSizeMax() / 2, construct_spr->GetSizeMax()); test_rect.SetPosition(test_rect.GetPosition() - Camera::GetInstance()->GetPosition()); GetMainWindow().RectangleColor(test_rect, primary_red_color, 1); } #endif } }
UINT8 HandleNonActivatedTargetCursor( SOLDIERTYPE *pSoldier, UINT16 usMapPos , BOOLEAN fShowAPs, BOOLEAN fRecalc, UINT32 uiCursorFlags ) { UINT16 usInHand; usInHand = pSoldier->inv[ HANDPOS ].usItem; if ( Item[ usInHand ].usItemClass != IC_THROWING_KNIFE ) { if (( ( gTacticalStatus.uiFlags & REALTIME ) || !( gTacticalStatus.uiFlags & INCOMBAT ) ) ) { //DetermineCursorBodyLocation( (UINT8)gusSelectedSoldier, FALSE, fRecalc ); DetermineCursorBodyLocation( (UINT8)gusSelectedSoldier, fShowAPs, fRecalc ); if ( pSoldier->fReloading || pSoldier->fPauseAim ) { return( ACTION_TARGET_RELOADING ); } } // Check for enough ammo... if ( !EnoughAmmo( pSoldier, FALSE, HANDPOS ) ) { // Check if ANY ammo exists..... if ( FindAmmoToReload( pSoldier, HANDPOS, NO_SLOT ) == NO_SLOT ) { // OK, use BAD reload cursor..... return( BAD_RELOAD_UICURSOR ); } else { // Check APs to reload... gsCurrentActionPoints = GetAPsToAutoReload( pSoldier ); gfUIDisplayActionPoints = TRUE; //gUIDisplayActionPointsOffX = 14; //gUIDisplayActionPointsOffY = 7; // OK, use GOOD reload cursor..... return( GOOD_RELOAD_UICURSOR ); } } } if ( gTacticalStatus.uiFlags & TURNBASED && (gTacticalStatus.uiFlags & INCOMBAT ) ) { DetermineCursorBodyLocation( (UINT8)gusSelectedSoldier, fShowAPs, fRecalc ); gsCurrentActionPoints = CalcTotalAPsToAttack( pSoldier, usMapPos, TRUE, (INT8)(pSoldier->bShownAimTime / 2) ); gfUIDisplayActionPoints = TRUE; gfUIDisplayActionPointsCenter = TRUE; if ( fShowAPs ) { if ( !EnoughPoints( pSoldier, gsCurrentActionPoints, 0 , FALSE ) ) { gfUIDisplayActionPointsInvalid = TRUE; } } else { //gfUIDisplayActionPointsBlack = TRUE; gfUIDisplayActionPoints = FALSE; } } //if ( gTacticalStatus.uiFlags & TURNBASED && !(gTacticalStatus.uiFlags & INCOMBAT ) ) { if ( fRecalc ) { if ( SoldierToLocationChanceToGetThrough( pSoldier, usMapPos, (INT8) gsInterfaceLevel, pSoldier->bTargetCubeLevel, NOBODY ) < OK_CHANCE_TO_GET_THROUGH ) { gfCannotGetThrough = TRUE; } else { gfCannotGetThrough = FALSE; } } // OK, if we begin to move, reset the cursor... if ( uiCursorFlags & MOUSE_MOVING ) { gfCannotGetThrough = FALSE; } if ( gfCannotGetThrough ) { if ( pSoldier->bDoBurst ) { return( ACTION_NOCHANCE_BURST_UICURSOR ); } else if ( Item[ usInHand ].usItemClass == IC_THROWING_KNIFE ) { return( BAD_THROW_UICURSOR ); } else { return( ACTION_NOCHANCE_SHOOT_UICURSOR ); } } } // Determine if good range if ( !InRange( pSoldier, usMapPos ) ) { // Flash cursor! // Check if we're in burst mode! if ( Item[ usInHand ].usItemClass == IC_THROWING_KNIFE ) { return( FLASH_THROW_UICURSOR ); } else if ( pSoldier->bDoBurst ) { //return( ACTION_FIRSTAID_RED ); return( ACTION_FLASH_BURST_UICURSOR ); } else { //return( ACTION_FIRSTAID_RED ); return( ACTION_FLASH_SHOOT_UICURSOR ); } } else { // Check if we're in burst mode! if ( Item[ usInHand ].usItemClass == IC_THROWING_KNIFE ) { return( GOOD_THROW_UICURSOR ); } else if ( pSoldier->bDoBurst ) { //return( ACTION_FIRSTAID_RED ); return( ACTION_TARGETBURST_UICURSOR ); } else { //return( ACTION_FIRSTAID_RED ); return( ACTION_SHOOT_UICURSOR ); } } }
UINT8 HandleNonActivatedTossCursor( SOLDIERTYPE *pSoldier, UINT16 sGridNo, BOOLEAN fRecalc, UINT32 uiCursorFlags, UINT8 ubItemCursor ) { INT16 sFinalGridNo; static BOOLEAN fBadCTGH = FALSE; BOOLEAN fArmed = FALSE; INT8 bLevel; OBJECTTYPE TempObject; INT8 bSlot; OBJECTTYPE * pObj; INT8 bAttachPos; // Check for enough ammo... if ( ubItemCursor == TRAJECTORYCURS ) { fArmed = TRUE; if ( !EnoughAmmo( pSoldier, FALSE, HANDPOS ) ) { // Check if ANY ammo exists..... if ( FindAmmoToReload( pSoldier, HANDPOS, NO_SLOT ) == NO_SLOT ) { // OK, use BAD reload cursor..... return( BAD_RELOAD_UICURSOR ); } else { // Check APs to reload... gsCurrentActionPoints = GetAPsToAutoReload( pSoldier ); gfUIDisplayActionPoints = TRUE; //gUIDisplayActionPointsOffX = 14; //gUIDisplayActionPointsOffY = 7; // OK, use GOOD reload cursor..... return( GOOD_RELOAD_UICURSOR ); } } } // Add APs.... if ( gTacticalStatus.uiFlags & TURNBASED && ( gTacticalStatus.uiFlags & INCOMBAT ) ) { if ( ubItemCursor == TRAJECTORYCURS ) { gsCurrentActionPoints = CalcTotalAPsToAttack( pSoldier, sGridNo, TRUE, (INT8)(pSoldier->bShownAimTime / 2) ); } else { gsCurrentActionPoints = MinAPsToThrow( pSoldier, sGridNo, TRUE ); } gfUIDisplayActionPoints = TRUE; gfUIDisplayActionPointsCenter = TRUE; // If we don't have any points and we are at the first refine, do nothing but warn! if ( !EnoughPoints( pSoldier, gsCurrentActionPoints, 0 , FALSE ) ) { gfUIDisplayActionPointsInvalid = TRUE; } } // OK, if we begin to move, reset the cursor... if ( uiCursorFlags & MOUSE_MOVING ) { EndPhysicsTrajectoryUI( ); } gfUIHandlePhysicsTrajectory = TRUE; if ( fRecalc ) { // Calculate chance to throw here..... if ( sGridNo == pSoldier->sGridNo ) { fBadCTGH = FALSE; } else { // ATE: Find the object to use... memcpy( &TempObject, &(pSoldier->inv[ HANDPOS ] ), sizeof( OBJECTTYPE ) ); // Do we have a launcable? pObj = &(pSoldier->inv[HANDPOS]); for (bAttachPos = 0; bAttachPos < MAX_ATTACHMENTS; bAttachPos++) { if (pObj->usAttachItem[ bAttachPos ] != NOTHING) { if ( Item[ pObj->usAttachItem[ bAttachPos ] ].usItemClass & IC_EXPLOSV ) { break; } } } if (bAttachPos != MAX_ATTACHMENTS) { CreateItem( pObj->usAttachItem[ bAttachPos ], pObj->bAttachStatus[ bAttachPos ], &TempObject ); } if (pSoldier->bWeaponMode == WM_ATTACHED && FindAttachment( &(pSoldier->inv[HANDPOS]), UNDER_GLAUNCHER ) != NO_SLOT ) { bSlot = FindAttachment( &(pSoldier->inv[HANDPOS]), UNDER_GLAUNCHER ); if ( bSlot != NO_SLOT ) { CreateItem( UNDER_GLAUNCHER, pSoldier->inv[HANDPOS].bAttachStatus[ bSlot ], &TempObject ); if ( !CalculateLaunchItemChanceToGetThrough( pSoldier, &TempObject, sGridNo, (INT8)gsInterfaceLevel, (INT16)( gsInterfaceLevel * 256 ), &sFinalGridNo, fArmed, &bLevel, TRUE ) ) { fBadCTGH = TRUE; } else { fBadCTGH = FALSE; } BeginPhysicsTrajectoryUI( sFinalGridNo, bLevel, fBadCTGH ); } } else { if ( !CalculateLaunchItemChanceToGetThrough( pSoldier, &TempObject, sGridNo, (INT8)gsInterfaceLevel, (INT16)( gsInterfaceLevel * 256 ), &sFinalGridNo, fArmed, &bLevel, TRUE ) ) { fBadCTGH = TRUE; } else { fBadCTGH = FALSE; } BeginPhysicsTrajectoryUI( sFinalGridNo, bLevel, fBadCTGH ); } } } if ( fBadCTGH ) { return( BAD_THROW_UICURSOR ); } return( GOOD_THROW_UICURSOR ); }
// FUNCTIONS FOR CURSOR DETERMINATION! UINT8 GetProperItemCursor( UINT8 ubSoldierID, UINT16 ubItemIndex, UINT16 usMapPos, BOOLEAN fActivated ) { SOLDIERTYPE *pSoldier; UINT32 uiCursorFlags; BOOLEAN fShowAPs = FALSE; BOOLEAN fRecalc = FALSE; INT16 sTargetGridNo = usMapPos; UINT8 ubCursorID=0; UINT8 ubItemCursor; pSoldier = MercPtrs[ ubSoldierID ]; fRecalc = GetMouseRecalcAndShowAPFlags( &uiCursorFlags, &fShowAPs ); // ATE: Update attacking weapon! // CC has added this attackingWeapon stuff and I need to update it constantly for // CTGH algorithms if ( gTacticalStatus.ubAttackBusyCount == 0 && Item[ pSoldier->inv[HANDPOS].usItem ].usItemClass & IC_WEAPON ) { pSoldier->usAttackingWeapon = pSoldier->inv[HANDPOS].usItem; } // Calculate target gridno! if ( gfUIFullTargetFound ) { sTargetGridNo = MercPtrs[ gusUIFullTargetID ]->sGridNo; } else { sTargetGridNo = usMapPos; } ubItemCursor = GetActionModeCursor( pSoldier ); switch( ubItemCursor ) { case PUNCHCURS: // Determine whether gray or red! ubCursorID = HandlePunchCursor( pSoldier, sTargetGridNo, fActivated, uiCursorFlags ); break; case KNIFECURS: ubCursorID = HandleKnifeCursor( pSoldier, sTargetGridNo, fActivated, uiCursorFlags ); break; case AIDCURS: ubCursorID = HandleAidCursor( pSoldier, usMapPos, fActivated, uiCursorFlags ); break; case TARGETCURS: // Set merc glow script SetMercGlowFast( ); if ( fActivated ) { ubCursorID = HandleActivatedTargetCursor( pSoldier, sTargetGridNo, fShowAPs, fRecalc, uiCursorFlags ); } else { ubCursorID = HandleNonActivatedTargetCursor( pSoldier, sTargetGridNo, fShowAPs, fRecalc, uiCursorFlags ); } // ATE: Only do this if we are in combat! if ( gCurrentUIMode == ACTION_MODE && ( gTacticalStatus.uiFlags & INCOMBAT ) ) { // Alrighty, let's change the cursor! if ( fRecalc && gfUIFullTargetFound ) { // ATE: Check for ammo if ( IsValidTargetMerc( (UINT8)gusUIFullTargetID ) && EnoughAmmo( pSoldier, FALSE, HANDPOS ) ) { // IF it's an ememy, goto confirm action mode if ( ( guiUIFullTargetFlags & ENEMY_MERC ) && ( guiUIFullTargetFlags & VISIBLE_MERC ) && !( guiUIFullTargetFlags & DEAD_MERC ) && !gfCannotGetThrough ) { guiPendingOverrideEvent = A_CHANGE_TO_CONFIM_ACTION; } } } } break; case TOSSCURS: case TRAJECTORYCURS: if ( fActivated ) { if ( !gfUIHandlePhysicsTrajectory ) { ubCursorID = HandleNonActivatedTossCursor( pSoldier, sTargetGridNo, fRecalc, uiCursorFlags, ubItemCursor ); } else { ubCursorID = HandleActivatedTossCursor( pSoldier, sTargetGridNo, ubItemCursor ); } } else { ubCursorID = HandleNonActivatedTossCursor( pSoldier, sTargetGridNo, fRecalc, uiCursorFlags, ubItemCursor ); } #if 0 if ( gCurrentUIMode == ACTION_MODE && ubItemCursor == TRAJECTORYCURS && ( gTacticalStatus.uiFlags & INCOMBAT ) ) { // Alrighty, let's change the cursor! if ( fRecalc && gfUIFullTargetFound ) { // ATE: Check for ammo if ( IsValidTargetMerc( (UINT8)gusUIFullTargetID ) && EnoughAmmo( pSoldier, FALSE, HANDPOS ) ) { // IF it's an ememy, goto confirm action mode if ( ( guiUIFullTargetFlags & ENEMY_MERC ) && ( guiUIFullTargetFlags & VISIBLE_MERC ) && !( guiUIFullTargetFlags & DEAD_MERC ) && !gfCannotGetThrough ) { guiPendingOverrideEvent = A_CHANGE_TO_CONFIM_ACTION; } } } } #endif break; case BOMBCURS: ubCursorID = HandleBombCursor( pSoldier, sTargetGridNo, fActivated, uiCursorFlags ); break; case REMOTECURS: ubCursorID = HandleRemoteCursor( pSoldier, sTargetGridNo, fActivated, uiCursorFlags ); break; case WIRECUTCURS: ubCursorID = HandleWirecutterCursor( pSoldier, sTargetGridNo, uiCursorFlags ); break; case REPAIRCURS: ubCursorID = HandleRepairCursor( pSoldier, sTargetGridNo, uiCursorFlags ); break; case JARCURS: ubCursorID = HandleJarCursor( pSoldier, sTargetGridNo, uiCursorFlags ); break; case TINCANCURS: ubCursorID = HandleTinCanCursor( pSoldier, sTargetGridNo, uiCursorFlags ); break; case REFUELCURS: ubCursorID = HandleRefuelCursor( pSoldier, sTargetGridNo, uiCursorFlags ); break; case INVALIDCURS: ubCursorID = INVALID_ACTION_UICURSOR; break; } if ( !( gTacticalStatus.uiFlags & INCOMBAT ) ) { if ( gfUIFullTargetFound ) { PauseRT( TRUE ); } else { PauseRT( FALSE ); } } return( ubCursorID ); }
void Parachute::Refresh() { if (Game::GetInstance()->GetRemainingTime() <= 0) return; if (Game::GetInstance()->ReadState() != Game::PLAYING) return; Character& active = ActiveCharacter(); Double speed = active.GetSpeedXY().Norm(); if (active.FootsInVacuum() && speed.IsNotZero()) { // We are falling if (!open && (speed > GameMode::GetInstance()->safe_fall)) { // with a sufficient speed if (EnoughAmmo() && !m_used_this_turn) { // We have enough ammo => start opening the parachute if (!m_used_this_turn) { UseAmmo(); m_used_this_turn = true; } active.SetAirResistFactor(cfg().air_resist_factor); active.SetWindFactor(cfg().wind_factor); open = true; img->animation.SetPlayBackward(false); img->Start(); active.SetSpeedXY(Point2d(0,0)); active.SetMovement("parachute"); Camera::GetInstance()->FollowObject(&active); } } } else { // We are on the ground if (open) { // The parachute is opened active.SetMovement("walk"); if (!closing) { // We have just hit the ground. Start closing animation img->animation.SetPlayBackward(true); img->animation.SetShowOnFinish(SpriteAnimation::show_blank); img->Start(); closing = true; return; } else { // The parachute is closing if (img->IsFinished()) { // The animation is finished... We are done with the parachute open = false; closing = false; UseAmmoUnit(); } } } m_used_this_turn = false; } if (open) { active.UpdateLastMovingTime(); // If parachute is open => character can move a little to the left or to the right const LRMoveIntention * lr_move_intention = active.GetLastLRMoveIntention(); if (lr_move_intention) { LRDirection direction = lr_move_intention->GetDirection(); active.SetDirection(direction); if (direction == DIRECTION_LEFT) active.SetExternForce(-cfg().force_side_displacement, 0.0); else active.SetExternForce(cfg().force_side_displacement, 0.0); } } }
bool Airhammer::ShouldAmmoUnitsBeDrawn() const { // Hide that the units are actually at maximum and not at 0 // when the ammo counter is at 0. return active || EnoughAmmo(); }