bool FCajunMaster::Move (AActor *actor, ticcmd_t *cmd) { fixed_t tryx, tryy; bool try_ok; int good; if (actor->movedir == DI_NODIR) return false; if ((unsigned)actor->movedir >= 8) I_Error ("Weird bot movedir!"); tryx = actor->x + 8*xspeed[actor->movedir]; tryy = actor->y + 8*yspeed[actor->movedir]; try_ok = CleanAhead (actor, tryx, tryy, cmd); if (!try_ok) //Anything blocking that could be opened etc.. { if (!spechit.Size ()) return false; actor->movedir = DI_NODIR; good = 0; line_t *ld; while (spechit.Pop (ld)) { bool tryit = true; if (ld->special == Door_LockedRaise && !P_CheckKeys (actor, ld->args[3], false)) tryit = false; else if (ld->special == Generic_Door && !P_CheckKeys (actor, ld->args[4], false)) tryit = false; if (tryit && (P_TestActivateLine (ld, actor, 0, SPAC_Use) || P_TestActivateLine (ld, actor, 0, SPAC_Push))) { good |= ld == actor->BlockingLine ? 1 : 2; } } if (good && ((pr_botopendoor() >= 203) ^ (good & 1))) { cmd->ucmd.buttons |= BT_USE; cmd->ucmd.forwardmove = FORWARDRUN; return true; } else return false; } else //Move forward. cmd->ucmd.forwardmove = FORWARDRUN; return true; }
bool P_ActivateLine (line_t *line, AActor *mo, int side, int activationType, DVector3 *optpos) { int lineActivation; INTBOOL repeat; INTBOOL buttonSuccess; BYTE special; if (!P_TestActivateLine (line, mo, side, activationType, optpos)) { return false; } bool remote = (line->special != 7 && line->special != 8 && (line->special < 11 || line->special > 14)); if (line->locknumber > 0 && !P_CheckKeys (mo, line->locknumber, remote)) return false; lineActivation = line->activation; repeat = line->flags & ML_REPEAT_SPECIAL; buttonSuccess = false; buttonSuccess = P_ExecuteSpecial(line->special, line, mo, side == 1, line->args[0], line->args[1], line->args[2], line->args[3], line->args[4]); special = line->special; if (!repeat && buttonSuccess) { // clear the special on non-retriggerable lines line->special = 0; } if (buttonSuccess) { if (activationType == SPAC_Use || activationType == SPAC_Impact || activationType == SPAC_Push) { P_ChangeSwitchTexture (line->sidedef[0], repeat, special); } } // some old WADs use this method to create walls that change the texture when shot. else if (activationType == SPAC_Impact && // only for shootable triggers (level.flags2 & LEVEL2_DUMMYSWITCHES) && // this is only a compatibility setting for an old hack! !repeat && // only non-repeatable triggers (special<Generic_Floor || special>Generic_Crusher) && // not for Boom's generalized linedefs special && // not for lines without a special tagManager.LineHasID(line, line->args[0]) && // Safety check: exclude edited UDMF linedefs or ones that don't map the tag to args[0] line->args[0] && // only if there's a tag (which is stored in the first arg) P_FindFirstSectorFromTag (line->args[0]) == -1) // only if no sector is tagged to this linedef { P_ChangeSwitchTexture (line->sidedef[0], repeat, special); line->special = 0; } // end of changed code if (developer && buttonSuccess) { Printf ("Line special %d activated on line %i\n", special, int(line - lines)); } return true; }
bool EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing, int tag, int speed, int delay, int lock, int lightTag, bool boomgen) { bool rtn = false; int secnum; sector_t* sec; if (lock != 0 && !P_CheckKeys (thing, lock, tag != 0)) return false; if (tag == 0) { // [RH] manual door if (!line) return false; // if the wrong side of door is pushed, give oof sound if (line->sidedef[1] == NULL) // killough { S_Sound (thing, CHAN_VOICE, "*usefail", 1, ATTN_NORM); return false; } // get the sector on the second side of activating linedef sec = line->sidedef[1]->sector; secnum = int(sec-sectors); // if door already has a thinker, use it if (sec->PlaneMoving(sector_t::ceiling)) { // Boom used remote door logic for generalized doors, even if they are manual if (boomgen) return false; if (sec->ceilingdata->IsKindOf (RUNTIME_CLASS(DDoor))) { DDoor *door = barrier_cast<DDoor *>(sec->ceilingdata); // ONLY FOR "RAISE" DOORS, NOT "OPEN"s if (door->m_Type == DDoor::doorRaise && type == DDoor::doorRaise) { if (door->m_Direction == -1) { door->m_Direction = 1; // go back up door->DoorSound (true); // [RH] Make noise } else if (!(line->activation & (SPAC_Push|SPAC_MPush))) // [RH] activate push doors don't go back down when you // run into them (otherwise opening them would be // a real pain). { if (!thing->player || thing->player->Bot != NULL) return false; // JDC: bad guys never close doors //Added by MC: Neither do bots. door->m_Direction = -1; // start going down immediately // Start the door close sequence. door->DoorSound(false, SN_CheckSequence(sec, CHAN_CEILING)); return true; } else { return false; } } } return false; } if (new DDoor (sec, type, speed, delay, lightTag)) rtn = true; } else { // [RH] Remote door secnum = -1; while ((secnum = P_FindSectorFromTag (tag,secnum)) >= 0) { sec = §ors[secnum]; // if the ceiling is already moving, don't start the door action if (sec->PlaneMoving(sector_t::ceiling)) continue; if (new DDoor (sec, type, speed, delay, lightTag)) rtn = true; } } return rtn; }
BOOL EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing, int tag, int speed, int delay, card_t lock) { BOOL rtn = false; int secnum; sector_t* sec; DDoor *door; if (lock && thing && !P_CheckKeys (thing->player, lock, tag)) return false; if (tag == 0) { // [RH] manual door if (!line) return false; // if the wrong side of door is pushed, give oof sound if (line->sidenum[1]==R_NOSIDE) // killough { UV_SoundAvoidPlayer (thing, CHAN_VOICE, "player/male/grunt1", ATTN_NORM); return false; } // get the sector on the second side of activating linedef sec = sides[line->sidenum[1]].sector; secnum = sec-sectors; if (sec->ceilingdata && P_MovingCeilingCompleted(sec)) { sec->ceilingdata->Destroy(); sec->ceilingdata = NULL; } // if door already has a thinker, use it door = static_cast<DDoor *>(sec->ceilingdata); // cph 2001/04/05 - // Original Doom didn't distinguish floor/lighting/ceiling // actions, so we need to do the same in demo compatibility mode. // [SL] 2011-06-20 - Credit to PrBoom for the fix if (!door) door = static_cast<DDoor *>(sec->floordata); if (!door) door = static_cast<DDoor *>(sec->lightingdata); if (door) { // ONLY FOR "RAISE" DOORS, NOT "OPEN"s if (door->m_Type == DDoor::doorRaise && type == DDoor::doorRaise) { if (sec->ceilingdata && sec->ceilingdata->IsKindOf (RUNTIME_CLASS(DDoor))) { if (door->m_Status == DDoor::closing) { // go back up door->m_Status = DDoor::reopening; return true; } else if (GET_SPAC(line->flags) == SPAC_PUSH) { // [RH] activate push doors don't go back down when you // run into them (otherwise opening them would be // a real pain). door->m_Line = line; return true; } else if (thing && thing->player) { // go back down door->m_Status = DDoor::closing; return true; } } return false; } } else { door = new DDoor(sec, line, type, speed, delay); P_AddMovingCeiling(sec); } if (door) { rtn = true; } } else { // [RH] Remote door secnum = -1; while ((secnum = P_FindSectorFromTag (tag,secnum)) >= 0) { sec = §ors[secnum]; // if the ceiling already moving, don't start the door action if (sec->ceilingdata) continue; door = new DDoor(sec, line, type, speed, delay); P_AddMovingCeiling(sec); if (door) rtn = true; } } return rtn; }
BOOL EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing, int tag, int speed, int delay, card_t lock) { BOOL rtn = false; int secnum; sector_t* sec; DDoor *door; if (lock && thing && !P_CheckKeys (thing->player, lock, tag)) return false; if (tag == 0) { // [RH] manual door if (!line) return false; // if the wrong side of door is pushed, give oof sound if (line->sidenum[1]==-1) // killough { UV_SoundAvoidPlayer (thing, CHAN_VOICE, "player/male/grunt1", ATTN_NORM); return false; } // get the sector on the second side of activating linedef sec = sides[line->sidenum[1]].sector; secnum = sec-sectors; // if door already has a thinker, use it if (sec->ceilingdata && sec->ceilingdata->IsKindOf (RUNTIME_CLASS(DDoor))) { door = static_cast<DDoor *>(sec->ceilingdata); door->m_Line = line; // ONLY FOR "RAISE" DOORS, NOT "OPEN"s if (door->m_Type == DDoor::doorRaise && type == DDoor::doorRaise) { if (door->m_Direction == -1) { door->m_Direction = 1; // go back up } else if (GET_SPAC(line->flags) != SPAC_PUSH) // [RH] activate push doors don't go back down when you // run into them (otherwise opening them would be // a real pain). { if (thing && !thing->player) return false; // JDC: bad guys never close doors // From Chocolate Doom: // When is a door not a door? // In Vanilla, door->direction is set, even though // "specialdata" might not actually point at a door. else if (sec->floordata && sec->floordata->IsKindOf (RUNTIME_CLASS(DPlat))) { // Erm, this is a plat, not a door. // This notably causes a problem in ep1-0500.lmp where // a plat and a door are cross-referenced; the door // doesn't open on 64-bit. // The direction field in vldoor_t corresponds to the wait // field in plat_t. Let's set that to -1 instead. DPlat *plat = static_cast<DPlat *>(sec->floordata); byte state; int count; plat->GetState(state, count); if (count >= 16) // ep1-0500 always returns a count of 16. return false; // We may be able to always return false? } else { door->m_Direction = -1; // try going back down anyway? } } return true; } } else { door = new DDoor(sec, line, type, speed, delay); } if (door) { rtn = true; } } else { // [RH] Remote door secnum = -1; while ((secnum = P_FindSectorFromTag (tag,secnum)) >= 0) { sec = §ors[secnum]; // if the ceiling already moving, don't start the door action if (sec->ceilingdata) continue; if (new DDoor (sec, line, type, speed, delay)) rtn = true; } } return rtn; }