| 5379 | } |
| 5380 | |
| 5381 | void bolt::pull_actor(actor *act, int dam) |
| 5382 | { |
| 5383 | if (!act || !can_pull(*act, dam) || act->resists_dislodge("being pulled")) |
| 5384 | return; |
| 5385 | |
| 5386 | // How far we'll try to pull the actor to make them adjacent to the source. |
| 5387 | const int distance = (act->pos() - source).rdist() - 1; |
| 5388 | ASSERT(distance > 0); |
| 5389 | |
| 5390 | const coord_def oldpos = act->pos(); |
| 5391 | ASSERT(ray.pos() == oldpos); |
| 5392 | |
| 5393 | coord_def newpos = oldpos; |
| 5394 | for (int dist_travelled = 0; dist_travelled < distance; ++dist_travelled) |
| 5395 | { |
| 5396 | const ray_def oldray(ray); |
| 5397 | |
| 5398 | ray.regress(); |
| 5399 | |
| 5400 | newpos = ray.pos(); |
| 5401 | if (newpos == oldray.pos() |
| 5402 | || cell_is_solid(newpos) |
| 5403 | || actor_at(newpos) |
| 5404 | || !act->can_pass_through(newpos) |
| 5405 | || !act->is_habitable(newpos)) |
| 5406 | { |
| 5407 | ray = oldray; |
| 5408 | break; |
| 5409 | } |
| 5410 | |
| 5411 | act->move_to(newpos, MV_DEFAULT, true); |
| 5412 | } |
| 5413 | |
| 5414 | if (newpos == oldpos) |
| 5415 | return; |
| 5416 | |
| 5417 | if (you.can_see(*act)) |
| 5418 | { |
| 5419 | mprf("%s %s yanked forward by the %s.", act->name(DESC_THE).c_str(), |
| 5420 | act->conj_verb("are").c_str(), name.c_str()); |
| 5421 | } |
| 5422 | |
| 5423 | if (act->pos() != newpos) |
| 5424 | act->collide(newpos, agent(), default_collision_damage(ench_power, true).roll()); |
| 5425 | |
| 5426 | act->finalise_movement(); |
| 5427 | } |
| 5428 | |
| 5429 | // Return true if the player's god will be unforgiving about the effects |
| 5430 | // of this beam. |
nothing calls this directly
no test coverage detected