/* you teleport a monster (via wand, spell, or poly'd q.mechanic attack); return false iff the attempt fails */ boolean u_teleport_mon(struct monst *mtmp, boolean give_feedback) { coord cc; if (mtmp->ispriest && *in_rooms(level, mtmp->mx, mtmp->my, TEMPLE)) { if (give_feedback) pline("%s resists your magic!", Monnam(mtmp)); return FALSE; } else if (level->flags.noteleport && u.uswallow && mtmp == u.ustuck) { if (give_feedback) pline("You are no longer inside %s!", mon_nam(mtmp)); unstuck(mtmp); rloc(mtmp, FALSE); } else if (is_rider(mtmp->data) && rn2(13) && enexto(&cc, level, u.ux, u.uy, mtmp->data)) rloc_to(mtmp, cc.x, cc.y); else rloc(mtmp, FALSE); return TRUE; }
int dozap(void) { struct obj *obj; xchar zx,zy; obj = getobj("/", "zap"); if(!obj) return(0); if(obj->spe < 0 || (obj->spe == 0 && rn2(121))) { pline("Nothing Happens."); return(1); } if(obj->spe == 0) pline("You wrest one more spell from the worn-out wand."); if(!(objects[obj->otyp].bits & NODIR) && !getdir(1)) return(1); /* make him pay for knowing !NODIR */ obj->spe--; if(objects[obj->otyp].bits & IMMEDIATE) { if(u.uswallow) bhitm(u.ustuck, obj); else if(u.dz) { if(u.dz > 0) { struct obj *otmp = o_at(u.ux, u.uy); if(otmp) bhito(otmp, obj); } } else bhit(u.dx,u.dy,rn1(8,6),0,bhitm,bhito,obj); } else { switch(obj->otyp){ case WAN_LIGHT: litroom(TRUE); break; case WAN_SECRET_DOOR_DETECTION: if(!findit()) return(1); break; case WAN_CREATE_MONSTER: { int cnt = 1; if(!rn2(23)) cnt += rn2(7) + 1; while(cnt--) makemon(NULL, u.ux, u.uy); } break; case WAN_WISHING: { char buf[BUFSZ]; struct obj *otmp; if(u.uluck + rn2(5) < 0) { pline("Unfortunately, nothing happens."); break; } pline("You may wish for an object. What do you want? "); getlin(buf); if(buf[0] == '\033') buf[0] = 0; otmp = readobjnam(buf); otmp = addinv(otmp); prinv(otmp); break; } case WAN_DIGGING: /* Original effect (approximately): * from CORR: dig until we pierce a wall * from ROOM: piece wall and dig until we reach * an ACCESSIBLE place. * Currently: dig for digdepth positions; * also down on request of Lennart Augustsson. */ { struct rm *room; int digdepth; if(u.uswallow) { struct monst *mtmp = u.ustuck; pline("You pierce %s's stomach wall!", monnam(mtmp)); mtmp->mhp = 1; /* almost dead */ unstuck(mtmp); mnexto(mtmp); break; } if(u.dz) { if(u.dz < 0) { pline("You loosen a rock from the ceiling."); pline("It falls on your head!"); losehp(1, "falling rock"); mksobj_at(ROCK, u.ux, u.uy); fobj->quan = 1; stackobj(fobj); if(Invisible) newsym(u.ux, u.uy); } else { dighole(); } break; } zx = u.ux+u.dx; zy = u.uy+u.dy; digdepth = 8 + rn2(18); Tmp_at(-1, '*'); /* open call */ while(--digdepth >= 0) { if(!isok(zx,zy)) break; room = &levl[zx][zy]; Tmp_at(zx,zy); if(!xdnstair){ if(zx < 3 || zx > COLNO-3 || zy < 3 || zy > ROWNO-3) break; if(room->typ == HWALL || room->typ == VWALL){ room->typ = ROOM; break; } } else if(room->typ == HWALL || room->typ == VWALL || room->typ == SDOOR || room->typ == LDOOR){ room->typ = DOOR; digdepth -= 2; } else if(room->typ == SCORR || !room->typ) { room->typ = CORR; digdepth--; } mnewsym(zx,zy); zx += u.dx; zy += u.dy; } mnewsym(zx,zy); /* not always necessary */ Tmp_at(-1,-1); /* closing call */ break; } default: buzz((int) obj->otyp - WAN_MAGIC_MISSILE, u.ux, u.uy, u.dx, u.dy); break; } } return(1); }
void Player::restoreCheckpoint() { setPosition(checkpoint->getPosition().x, checkpoint->getPosition().y); unstuck(); }
/* Drive during race. */ void Driver::drive(tCarElt* car, tSituation *s) { update(car, s); isStuck(car) ? unstuck(car) : followcenter(car); }
void CollisionEngine::update(float delta) { if (objects.empty()) return; CollisionData col_data; float frame=delta; float min_time=frame; int max_tries=200; do { min_time=frame; for(Objects::iterator i = objects.begin(); i != objects.end(); ++i) { for(Objects::iterator j = i + 1; j != objects.end(); ++j) { if (i != j && (((*i)->get_is_domains() & (*j)->get_check_domains()) || ((*j)->get_is_domains() & (*i)->get_check_domains()))) { CollisionData r = collide(**i, **j, frame); if(r.state!=CollisionData::NONE) { if (min_time > r.col_time && r.col_time>=0) { r.object1 = *i; r.object2 = *j; col_data = r; min_time = r.col_time; if (min_time > 0.0005f) min_time -= 0.0005f; } } } } } // move till first collision (or till end, when no collision occured) if(min_time>0) { for(Objects::iterator i = objects.begin(); i != objects.end(); ++i) { update(**i,min_time); } } // report collision if (min_time < frame) { collision (col_data); } frame-=min_time; min_time=0; // check tries --max_tries; if (max_tries == 0) std::cerr<<"Too much tries in collision detection"<<std::endl; }while (min_time < frame && max_tries>0); //return; // uncomment, if you want no unstucking // check penetration and resolve bool penetration = true; int maxtries=15; while(penetration) { penetration=false; // FIXME: support this by some spatial container for(Objects::iterator i = objects.begin(); i != objects.end(); ++i) { if(!(*i)->unstuck()) continue; for(Objects::iterator j = i+1; j != objects.end(); ++j) { if(!(*j)->unstuck()) continue; if (i != j && ((*i)->unstuck_movable() || ((*j)->unstuck_movable()))) { CollisionData r = collide(**i, **j, 0); if(r.state!=CollisionData::NONE) { penetration=true; unstuck(**i, **j, delta/3.0f); } } } } maxtries--; if(maxtries==0) break; } }
struct monst * tamedog(struct monst *mtmp, struct obj *obj) { struct monst *mtmp2; /* The Wiz, Medusa and the quest nemeses aren't even made peaceful. */ if (mtmp->iswiz || mtmp->data == &mons[PM_MEDUSA] || (mtmp->data->mflags3 & M3_WANTSARTI)) return NULL; /* worst case, at least it'll be peaceful; this uses the main RNG because realtime effects means that this won't really sync anyway; this also calls set_malign (thus there's no need for the caller to call it after calling tamedog()) */ msethostility(mtmp, FALSE, TRUE); if (flags.moonphase == FULL_MOON && night() && rn2(6) && obj && mtmp->data->mlet == S_DOG) return NULL; /* If we cannot tame it, at least it's no longer afraid. */ mtmp->mflee = 0; mtmp->mfleetim = 0; /* make grabber let go now, whether it becomes tame or not */ if (mtmp == u.ustuck) { if (Engulfed) expels(mtmp, mtmp->data, TRUE); else if (!(Upolyd && sticks(youmonst.data))) unstuck(mtmp); } /* feeding it treats makes it tamer */ if (mtmp->mtame && obj) { int tasty; if (mtmp->mcanmove && !mtmp->mconf && !mtmp->meating && ((tasty = dogfood(mtmp, obj)) == DOGFOOD || (tasty <= ACCFOOD && CONST_EDOG(mtmp)->hungrytime <= moves))) { /* pet will "catch" and eat this thrown food */ if (canseemon(mtmp)) { boolean big_corpse = (obj->otyp == CORPSE && obj->corpsenm >= LOW_PM && mons[obj->corpsenm].msize > mtmp->data->msize); pline("%s catches %s%s", Monnam(mtmp), the(xname(obj)), !big_corpse ? "." : ", or vice versa!"); } else if (cansee(mtmp->mx, mtmp->my)) pline("%s.", Tobjnam(obj, "stop")); /* dog_eat expects a floor object */ place_object(obj, level, mtmp->mx, mtmp->my); dog_eat(mtmp, obj, mtmp->mx, mtmp->my, FALSE); /* eating might have killed it, but that doesn't matter here; a non-null result suppresses "miss" message for thrown food and also implies that the object has been deleted */ return mtmp; } else return NULL; } if (mtmp->mtame || !mtmp->mcanmove || /* monsters with conflicting structures cannot be tamed */ mtmp->isshk || mtmp->isgd || mtmp->ispriest || mtmp->isminion || is_covetous(mtmp->data) || is_human(mtmp->data) || (is_demon(mtmp->data) && !is_demon(youmonst.data)) || (obj && dogfood(mtmp, obj) >= MANFOOD)) return NULL; if (mtmp->m_id == u.quest_status.leader_m_id) return NULL; /* make a new monster which has the pet extension */ mtmp2 = newmonst(MX_EDOG, mtmp->mnamelth); *mtmp2 = *mtmp; mtmp2->mxtyp = MX_EDOG; mtmp2->mxlth = sizeof (struct edog); if (mtmp->mnamelth) strcpy(NAME_MUTABLE(mtmp2), NAME(mtmp)); initedog(mtmp2); replmon(mtmp, mtmp2); /* `mtmp' is now obsolete */ if (obj) { /* thrown food */ /* defer eating until the edog extension has been set up */ place_object(obj, level, mtmp2->mx, mtmp2->my); /* put on floor */ /* devour the food (might grow into larger, genocided monster) */ if (dog_eat(mtmp2, obj, mtmp2->mx, mtmp2->my, TRUE) == 2) return mtmp2; /* oops, it died... */ /* `obj' is now obsolete */ } if (mtmp2->dlevel == level) newsym(mtmp2->mx, mtmp2->my); if (attacktype(mtmp2->data, AT_WEAP)) { mtmp2->weapon_check = NEED_HTH_WEAPON; mon_wield_item(mtmp2); } return mtmp2; }