/* Copyright (C) 1998 Pyrosoft Inc. (www.pyrosoftgames.com), Matthew Bogue This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "Weapon.hpp" #include "UnitMessageTypes.hpp" #include "UnitInterface.hpp" #include "NetworkState.hpp" // NOTE: Temp until new sprites put in #include "WorldViewInterface.hpp" #include "ScreenSurface.hpp" #include "Util/Exception.hpp" #include "System/Sound.hpp" #include "ParticleInterface.hpp" #include "WeaponGlobals.hpp" #include "Util/Math.hpp" void Weapon::init() { //packFiles(); gMissleMediumPackedSurface.load("pics/particles/missles/pak/misslesMedium.pak"); gMissleSmallPackedSurface.load("pics/particles/missles/pak/misslesSmall.pak"); gShellPackedSurface.load("pics/particles/shells/pak/shells.pak"); Surface temp; PackedSurface pack; gMissleThrustPackedSurface.load("pics/particles/lights/pak/missleThrust.pak"); gMissleGroundLightPackedSurface.load("pics/particles/lights/pak/missleGroundLight.pak"); } Weapon::Weapon(UnitID &owner, unsigned short owner_type_id, unsigned short damage, iXY &start, iXY &end) { // I use this to line things up, so leave this in here when this // get redone. thank you. direction = Math::unitDirection(start, end); owner_id = owner; Weapon::owner_type_id = owner_type_id; damage_factor = damage; fsmFlight_state = _fsmFlight_in_flight; path.set_path( start, end ); path.increment( &location, 15 ); fsm_timer.changeRate( 20 ); lifecycle_status = _lifecycle_weapon_in_fight; // This is getting called as well in all derived class constructors. shell.setAttrib( location, 0 ); } void Weapon::fsmFlight( void ) { bool end_cycle = false; do { switch( fsmFlight_state ) { case _fsmFlight_idle: end_cycle = true; break; case _fsmFlight_in_flight: if ( path.increment( &location, 4 ) == true ) { fsmFlight_state = _fsmFlight_on_target; } end_cycle = true; break; case _fsmFlight_on_target: { UMesgWeaponHit weapon_hit; if (NetworkState::status == _network_state_server) { weapon_hit.setHeader(0, _umesg_flag_broadcast); weapon_hit.message_id = _umesg_weapon_hit; weapon_hit.setOwnerUnitID(owner_id); weapon_hit.setHitLocation(location); weapon_hit.setDamageFactor(damage_factor); UnitInterface::sendMessage( &weapon_hit ); } fsmFlight_state = _fsmFlight_idle; lifecycle_status = _lifecycle_weapon_in_active; //SFX sound->playSound("hit_target"); // ** Particle Shit iXY loc = iXY( location.x, location.y ); ParticleInterface::addMiss(loc, Weapon::owner_type_id); end_cycle = true; break; } } } while ( end_cycle == false ); } void Weapon::updateStatus( void ) { if ( fsm_timer.count() ) fsmFlight(); // ** NOTE: Temp unit new sprites put in iRect world_win; shell.setWorldPos( location ); WorldViewInterface::getViewWindow(&world_win ); if ( shell.isVisible( world_win ) == true ) { shell.blit(screen, world_win ); } } int Weapon::getGoalAngle(const iXY &start, const iXY &end) { // Get the slope of the line from the object to the mouse float num = start.y - end.y; // invert Y since screen is inverted float den = end.x - start.x; // Figure out what angle we want to be pointing, in radians. This // value is from -PI, which points left, moving counterclockwise to 0, // which points right, continuing clockwise to +PI, which points // back left. float goalAngleRad = atan2(num, den); // Fix the goal angle around to match up with the way our angle // measurements work. We measure with 0 pointing north, moving around // clockwise. We also want to measure the angle from 0.0 to 1.0. float ourGoalAngle = ((M_PI / 2) - goalAngleRad) / (M_PI * 2); int angle = (int) (ourGoalAngle * 360); while (angle < 0) { angle += 360; } while (angle >= 360) { angle -= 360; } return angle; }