00001 // AngryStone - A spiked block that charges towards the player 00002 // Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de> 00003 // 00004 // This program is free software: you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation, either version 3 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // This program is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with this program. If not, see <http://www.gnu.org/licenses/>. 00016 00017 #include "badguy/angrystone.hpp" 00018 00019 #include "object/player.hpp" 00020 #include "sprite/sprite.hpp" 00021 #include "supertux/object_factory.hpp" 00022 00023 static const float CHARGE_SPEED = 240; 00024 00025 static const float CHARGE_TIME = .5; 00026 static const float ATTACK_TIME = 1; 00027 static const float RECOVER_TIME = .5; 00028 00029 AngryStone::AngryStone(const Reader& reader) : 00030 BadGuy(reader, "images/creatures/angrystone/angrystone.sprite"), 00031 attackDirection(), 00032 oldWallDirection(), 00033 timer(), 00034 state(IDLE) 00035 { 00036 physic.set_velocity_x(0); 00037 physic.set_velocity_y(0); 00038 physic.enable_gravity(true); 00039 sprite->set_action("idle"); 00040 } 00041 00042 void 00043 AngryStone::collision_solid(const CollisionHit& hit) 00044 { 00045 // TODO 00046 (void) hit; 00047 #if 0 00048 if ((state == ATTACKING) && 00049 (hit.normal.x == -attackDirection.x) && (hit.normal.y == attackDirection.y)) { 00050 state = IDLE; 00051 sprite->set_action("idle"); 00052 physic.set_velocity_x(0); 00053 physic.set_velocity_y(0); 00054 physic.enable_gravity(true); 00055 oldWallDirection.x = attackDirection.x; 00056 oldWallDirection.y = attackDirection.y; 00057 } 00058 #endif 00059 } 00060 00061 void 00062 AngryStone::kill_fall() 00063 { 00064 //prevents AngryStone from getting killed by other enemies or the player 00065 } 00066 00067 HitResponse 00068 AngryStone::collision_badguy(BadGuy& badguy, const CollisionHit& ) 00069 { 00070 if (state == ATTACKING) { 00071 badguy.kill_fall(); 00072 return FORCE_MOVE; 00073 } 00074 00075 return FORCE_MOVE; 00076 } 00077 00078 void 00079 AngryStone::active_update(float elapsed_time) { 00080 BadGuy::active_update(elapsed_time); 00081 00082 if (state == IDLE) { 00083 MovingObject* player = this->get_nearest_player(); 00084 if(player) { 00085 MovingObject* badguy = this; 00086 const Vector playerPos = player->get_pos(); 00087 const Vector badguyPos = badguy->get_pos(); 00088 float dx = (playerPos.x - badguyPos.x); 00089 float dy = (playerPos.y - badguyPos.y); 00090 00091 float playerHeight = player->get_bbox().p2.y - player->get_bbox().p1.y; 00092 float badguyHeight = badguy->get_bbox().p2.y - badguy->get_bbox().p1.y; 00093 00094 float playerWidth = player->get_bbox().p2.x - player->get_bbox().p1.x; 00095 float badguyWidth = badguy->get_bbox().p2.x - badguy->get_bbox().p1.x; 00096 00097 if ((dx > -playerWidth) && (dx < badguyWidth)) { 00098 if (dy > 0) { 00099 attackDirection.x = 0; 00100 attackDirection.y = 1; 00101 } else { 00102 attackDirection.x = 0; 00103 attackDirection.y = -1; 00104 } 00105 if ((attackDirection.x != oldWallDirection.x) || (attackDirection.y != oldWallDirection.y)) { 00106 sprite->set_action("charging"); 00107 timer.start(CHARGE_TIME); 00108 state = CHARGING; 00109 } 00110 } else 00111 if ((dy > -playerHeight) && (dy < badguyHeight)) { 00112 if (dx > 0) { 00113 attackDirection.x = 1; 00114 attackDirection.y = 0; 00115 } else { 00116 attackDirection.x = -1; 00117 attackDirection.y = 0; 00118 } 00119 if ((attackDirection.x != oldWallDirection.x) || (attackDirection.y != oldWallDirection.y)) { 00120 sprite->set_action("charging"); 00121 timer.start(CHARGE_TIME); 00122 state = CHARGING; 00123 } 00124 } 00125 00126 } 00127 } 00128 00129 if (state == CHARGING) { 00130 if (timer.check()) { 00131 sprite->set_action("attacking"); 00132 timer.start(ATTACK_TIME); 00133 state = ATTACKING; 00134 physic.enable_gravity(false); 00135 physic.set_velocity_x(CHARGE_SPEED * attackDirection.x); 00136 physic.set_velocity_y(CHARGE_SPEED * attackDirection.y); 00137 oldWallDirection.x = 0; 00138 oldWallDirection.y = 0; 00139 } 00140 } 00141 00142 if (state == ATTACKING) { 00143 if (timer.check()) { 00144 timer.start(RECOVER_TIME); 00145 state = RECOVERING; 00146 sprite->set_action("idle"); 00147 physic.enable_gravity(true); 00148 physic.set_velocity_x(0); 00149 physic.set_velocity_y(0); 00150 } 00151 } 00152 00153 if (state == RECOVERING) { 00154 if (timer.check()) { 00155 state = IDLE; 00156 sprite->set_action("idle"); 00157 physic.enable_gravity(true); 00158 physic.set_velocity_x(0); 00159 physic.set_velocity_y(0); 00160 } 00161 } 00162 00163 } 00164 00165 /* EOF */