void fear() { char mflag; char key; int x,y; int xdir,ydir; int mon; int i; key = get_dir(&xdir,&ydir); x = player.x; y = player.y; mflag = ' '; while (mflag == ' ') { x += xdir; y += ydir; if (player.map[x][y] == 3) mflag = '*'; if (player.map[x][y] == 38) mflag = '*'; if (player.map[x][y] == 39) mflag = '*'; if (player.map[x][y] == 21) mflag = '*'; if (player.map[x][y] < 0) mflag = '*'; if (player.map[x][y]>400 && player.map[x][y]<500) mflag = '*'; if (in_sight(x,y) == '*') { show_sprite(x-player.map_x,y-player.map_y,80); delay(100); show_spot(x,y); } } if (player.map[x][y] < 0 || (player.map[x][y]>400 && player.map[x][y]<500)) { if (in_arena == 'Y') mon = player.map[x][y] - 400; else mon = player.map[x][y]; if (in_arena == 'Y') i=50+5*(player.level-player.monster[mon][a_mon].level); else i=50+5*(player.level-player.monster[1][mon].level); if (in_arena == 'Y' && player.monster[mon][a_mon].special == 1) i=0; if (in_arena != 'Y' && player.monster[1][mon].special == 1) i=0; if (u_random(100) < i) { clear_prompt(); prompt("SCARED !!!"); if (in_sight(x,y) == '*') { show_sprite(x-player.map_x,y-player.map_y,80); delay(250); show_spot(x,y); } if (in_arena != 'Y') player.monster[1][mon].fear=u_random(5*(player.level-player.monster[1][mon].level)); if (in_arena == 'Y') player.monster[mon][a_mon].fear=u_random(5*(player.level-player.monster[mon][a_mon].level)); } else { clear_prompt(); prompt("Fizzle. . . "); } } }
std::size_t get_closest_entity(std::size_t id, COND& condition, bool only_sight = true) const { auto phys_comp = entities_.get_component<PhysicsComponent>(id); std::size_t closest_id = Component::NO_ENTITY; Ogre::Real min_distance = std::numeric_limits<Ogre::Real>::max(); if(phys_comp) { for(auto& ent : get_container<CONT>()) { if(ent.first == id || !condition(ent.first)) continue; auto enemy_phys_comp = entities_.get_component<PhysicsComponent>(ent.first); if(enemy_phys_comp) { auto dist = phys_comp->position.squaredDistance(enemy_phys_comp->position); if(enemy_phys_comp && dist < min_distance && (!only_sight || in_sight(id, ent.first)) && util::pathfind(entities_, id, ent.first, util::heuristic::MANHATTAN_DISTANCE{entities_}, false)) { min_distance = dist; closest_id = ent.first; } } } } return closest_id; }
void area25(int damage) { int x,y; int x1,y1; int mon; int i; x1 = player.x; y1 = player.y; if (x1<2) x1=2; else if (x1>98) x1 = 98; if (y1<2) y1=2; else if (y1>98) y1 = 98; for (x=x1-2; x<=x1+2; x++) for (y=y1-2; y<=y1+2; y++) if (player.map[x][y] < 0 || (player.map[x][y]>400 && player.map[x][y]<500)) { if (in_arena == 'Y') mon = player.map[x][y] - 400; else mon = player.map[x][y]; i = 90; if (in_arena == 'Y' && player.monster[mon][a_mon].special == 1) i = 0; if (in_arena != 'Y' && player.monster[1][mon].special == 1) i = 0; if (u_random(100) < i) { clear_prompt(); noise(1000,100); prompt("HIT !!!"); if (in_arena != 'Y' && player.monster[1][mon].special > 9) { player.align -= 20; player.monster[1][mon].special -= 10; if (player.align < 0) player.align = 0; } if (in_arena == 'Y' && player.monster[mon][a_mon].special > 9) { player.align -= 20; player.monster[mon][a_mon].special -= 10; if (player.align < 0) player.align = 0; } if (in_sight(x,y) == '*') { show_sprite(x-player.map_x,y-player.map_y,80); delay(250); show_spot(x,y); } i = u_random(damage) + 1; if (in_arena == 'Y') player.monster[mon][a_mon].hp -= i; else player.monster[1][mon].hp -= i; if (in_arena == 'Y') i=player.monster[mon][a_mon].hp; else i=player.monster[1][mon].hp; if (i <= 0) { clear_prompt(); if (in_arena != 'Y') { gain_exp(player.monster[1][mon].exp); player.map[x][y] = player.monster[1][mon].prev; } if (in_arena == 'Y') { gain_exp(player.monster[mon][a_mon].exp); player.map[x][y] = player.monster[mon][a_mon].prev; } show_spot(x,y); if (in_arena != 'Y' && player.monster[1][mon].special > 9) { player.align -= 20; if (player.align < 0) player.align = 0; } if (in_arena == 'Y' && player.monster[mon][a_mon].special > 9) { player.align -= 20; if (player.align < 0) player.align = 0; } show_side(); } } else { clear_prompt(); prompt("Fizzle. . ."); } } }
void drain(int damage) { char key; char buffer[32]; int x,y; int xdir,ydir; int mon; int i; key = get_dir(&xdir,&ydir); x = player.x + xdir; y = player.y + ydir; if (player.map[x][y] < 0 || (player.map[x][y]>400 && player.map[x][y]<500)) { if (in_arena == 'Y') mon = player.map[x][y] - 400; else mon = player.map[x][y]; i = 90; if (in_arena == 'Y' && player.monster[mon][a_mon].special == 1) i = 0; if (in_arena != 'Y' && player.monster[1][mon].special == 1) i = 0; if (u_random(100) < i) { clear_prompt(); noise(1000,100); prompt("HIT !!!"); if (in_arena != 'Y' && player.monster[1][mon].special > 9) { player.align -= 20; player.monster[1][mon].special -= 10; if (player.align < 0) player.align = 0; } if (in_arena == 'Y' && player.monster[mon][a_mon].special > 9) { player.align -= 20; player.monster[mon][a_mon].special -= 10; if (player.align < 0) player.align = 0; } if (in_sight(x,y) == '*') { show_sprite(x-player.map_x,y-player.map_y,80); delay(250); show_spot(x,y); } i = u_random(damage) + 1; player.chp += i; if (player.chp > player.mhp) player.chp = player.mhp; if (in_arena == 'Y') player.monster[mon][a_mon].hp -= i; else player.monster[1][mon].hp -= i; if (in_arena == 'Y') i=player.monster[mon][a_mon].hp; else i=player.monster[1][mon].hp; if (i <= 0) { clear_prompt(); if (in_arena != 'Y') { sprintf(buffer,"Exp=%.0f",player.monster[1][mon].exp); prompt(buffer); player.exp += player.monster[1][mon].exp; player.map[x][y] = player.monster[1][mon].prev; } if (in_arena == 'Y') { sprintf(buffer,"Exp=%.0f",player.monster[mon][a_mon].exp); prompt(buffer); player.exp += player.monster[mon][a_mon].exp; player.map[x][y] = player.monster[mon][a_mon].prev; } show_spot(x,y); if (in_arena != 'Y' && player.monster[1][mon].special > 9) { player.align -= 20; if (player.align < 0) player.align = 0; } if (in_arena == 'Y' && player.monster[mon][a_mon].special > 9) { player.align -= 20; if (player.align < 0) player.align = 0; } show_side(); } } else { clear_prompt(); prompt("Fizzle. . ."); } } }
void CombatSystem::update(Ogre::Real delta) { // Running away. if(!run_away_queue_.empty()) { run_away_from_( std::get<0>(run_away_queue_.front()), std::get<1>(run_away_queue_.front()), std::get<2>(run_away_queue_.front()) ); run_away_queue_.pop(); } // Autoattacks. for(auto& ent : entities_.get_component_container<CombatComponent>()) { if(ent.second.cd_time < ent.second.cooldown) { ent.second.cd_time += delta; continue; } else ent.second.cd_time = 0; if(ent.second.curr_target != Component::NO_ENTITY && entities_.exists(ent.second.curr_target)) { auto phys_comp = entities_.get_component<PhysicsComponent>(ent.first); auto target_phys_comp = entities_.get_component<PhysicsComponent>(ent.second.curr_target); auto range = ent.second.range * ent.second.range; auto task_comp = entities_.get_component<TaskHandlerComponent>(ent.first); if(phys_comp && target_phys_comp) { auto dist = phys_comp->position.squaredDistance(target_phys_comp->position); auto path_comp = entities_.get_component<PathfindingComponent>(ent.first); /** * Check if the target is in range and in sight and if so, attack, otherwise * pursue the target if necessary. */ bool is_in_sight{in_sight(ent.first, ent.second.curr_target)}; bool kill_task_assigned{task_comp ? (TaskHelper::get_task_type(entities_, task_comp->curr_task) == TASK_TYPE::KILL) : false}; bool on_path{path_comp && !path_comp->path_queue.empty()}; bool is_in_range{dist <= range}; if((!is_in_range || !is_in_sight) && !on_path && kill_task_assigned) { if(ent.second.pursue) { // Order it to go after the target again. TaskHelper::add_task(entities_, ent.first, ent.second.curr_target, true); task_comp->task_queue.push_front(task_comp->curr_task); auto new_task = TaskHelper::create_task(entities_, ent.second.curr_target, TASK_TYPE::GET_IN_RANGE); task_comp->task_queue.push_front(new_task); task_comp->curr_task = Component::NO_ENTITY; } else { // Just give up. TaskHelper::cancel_task(entities_, task_comp->curr_task); } ent.second.curr_target = Component::NO_ENTITY; } else if(is_in_range && is_in_sight) { if(on_path) // Enemy came to us, just start attacking! { AnimationHelper::stop(entities_, ent.first); path_comp->path_queue.clear(); } auto dmg = CombatHelper::get_dmg(ent.second.min_dmg, ent.second.max_dmg); GraphicsHelper::look_at(entities_, ent.first, ent.second.curr_target); switch(ent.second.atk_type) { case ATTACK_TYPE::MELEE: AnimationHelper::play(entities_, ent.first, ANIMATION_TYPE::HIT, false); HealthHelper::sub_health(entities_, ent.second.curr_target, dmg); OnHitHelper::call(entities_, ent.second.curr_target, ent.first); if(HealthHelper::get_health(entities_, ent.second.curr_target) <= 0) { DestructorHelper::destroy(entities_, ent.second.curr_target, false, ent.first); ent.second.curr_target = Component::NO_ENTITY; ent.second.cd_time = ent.second.cooldown; // Allows to attack again instantly. if(task_comp && TaskHelper::get_task_type(entities_, task_comp->curr_task) == TASK_TYPE::KILL) TaskHelper::cancel_task(entities_, task_comp->curr_task); } break; case ATTACK_TYPE::RANGED: AnimationHelper::play(entities_, ent.first, ANIMATION_TYPE::HIT, false); create_homing_projectile(ent.first, ent.second); break; } } else if(!kill_task_assigned) ent.second.curr_target = Component::NO_ENTITY; } else // Target killed or ran away. ent.second.curr_target = Component::NO_ENTITY; } } // Homing projectiles. for(auto& ent : entities_.get_component_container<HomingComponent>()) { if(ent.second.target == Component::NO_ENTITY) continue; // Manually spawned. else if(!entities_.exists(ent.second.target)) // Target killed. DestructorHelper::destroy(entities_, ent.first); auto mov_comp = entities_.get_component<MovementComponent>(ent.first); auto phys_comp = entities_.get_component<PhysicsComponent>(ent.first); auto graph_comp = entities_.get_component<GraphicsComponent>(ent.first); auto enemy_phys_comp = entities_.get_component<PhysicsComponent>(ent.second.target); if(mov_comp && phys_comp && graph_comp && enemy_phys_comp && graph_comp->node && graph_comp->entity) { // Moves the homing projectile in the target's direction and checks if hit occured. auto& pos = phys_comp->position; auto dir = enemy_phys_comp->position - pos; dir.normalise(); pos += dir * mov_comp->speed_modifier; graph_comp->node->setPosition(pos); auto radius = graph_comp->entity->getWorldBoundingSphere(true).getRadius(); if(pos.squaredDistance(enemy_phys_comp->position) < radius * radius) { // That's a hit. HealthHelper::sub_health(entities_, ent.second.target, ent.second.dmg); OnHitHelper::call(entities_, ent.second.target, ent.second.source); if(HealthHelper::get_health(entities_, ent.second.target) <= 0) { DestructorHelper::destroy(entities_, ent.second.target, false, ent.second.source); auto task_comp = entities_.get_component<TaskHandlerComponent>(ent.second.source); if(task_comp && TaskHelper::get_task_type(entities_, task_comp->curr_task) == TASK_TYPE::KILL) TaskHelper::cancel_task(entities_, task_comp->curr_task); } DestructorHelper::destroy(entities_, ent.first, false, ent.second.target); } } } }