/** * @brief Opens/closes a door * @note Use function for func_door * @todo Check if the door can be opened or closed - there should not be * anything in the way (e.g. an actor) */ static bool Door_Use (edict_t *door, edict_t *activator) { if (door->doorState == STATE_CLOSED) { door->doorState = STATE_OPENED; /* change rotation/origin and relink */ if (door->type == ET_DOOR) { if (door->dir & DOOR_OPEN_REVERSE) door->angles[door->dir & 3] -= DOOR_ROTATION_ANGLE; else door->angles[door->dir & 3] += DOOR_ROTATION_ANGLE; } else if (door->type == ET_DOOR_SLIDING) { Door_SlidingUse(door); } gi.LinkEdict(door); /* maybe the server called this because the door starts opened */ if (G_MatchIsRunning()) { /* let everybody know, that the door opens */ G_EventDoorOpen(door); if (door->noise[0] != '\0') G_EventSpawnSound(PM_ALL, false, door, door->origin, door->noise); } } else if (door->doorState == STATE_OPENED) { door->doorState = STATE_CLOSED; /* change rotation and relink */ if (door->type == ET_DOOR) { if (door->dir & DOOR_OPEN_REVERSE) door->angles[door->dir & 3] += DOOR_ROTATION_ANGLE; else door->angles[door->dir & 3] -= DOOR_ROTATION_ANGLE; } else if (door->type == ET_DOOR_SLIDING) { Door_SlidingUse(door); } gi.LinkEdict(door); /* closed is the standard, opened is handled above - we need an active * team here already */ if (G_MatchIsRunning()) { /* let everybody know, that the door closes */ G_EventDoorClose(door); if (door->noise[0] != '\0') G_EventSpawnSound(PM_ALL, false, door, door->origin, door->noise); } } else return false; /* Update model orientation */ gi.SetInlineModelOrientation(door->model, door->origin, door->angles); Com_DPrintf(DEBUG_GAME, "Server processed door movement.\n"); /* Update path finding table */ G_RecalcRouting(door->model); if (activator && G_IsLivingActor(activator)) { /* Check if the player appears/perishes, seen from other teams. */ G_CheckVis(activator, true); /* Calc new vis for the activator. */ G_CheckVisTeamAll(activator->team, false, activator); } return true; }
/** * @brief Opens/closes a door * @note Use function for func_door * @todo Check if the door can be opened or closed - there should not be * anything in the way (e.g. an actor) */ static bool Door_Use (edict_t *door, edict_t *activator) { int opening = 1; if (door->doorState == STATE_CLOSED) { door->doorState = STATE_OPENED; opening = 1; } else if (door->doorState == STATE_OPENED) { door->doorState = STATE_CLOSED; opening = -1; } else return false; /* remember the old location */ AABB oldAABB; gi.GetInlineModelAABB(door->model, oldAABB); GridBox rerouteOldBox(oldAABB); /* change rotation and relink */ if (door->type == ET_DOOR) { if (door->dir & DOOR_OPEN_REVERSE) opening *= -1; door->angles[door->dir & 3] += DOOR_ROTATION_ANGLE * opening; } else if (door->type == ET_DOOR_SLIDING) { Door_SlidingUse(door); } gi.LinkEdict(door); /* maybe the server called this because the door starts opened */ if (G_MatchIsRunning()) { /* let everybody know, that the door moves */ if (door->doorState == STATE_OPENED) G_EventDoorOpen(door); else G_EventDoorClose(door); if (door->noise[0] != '\0') { const playermask_t playerMask = G_GetClosePlayerMask(door->origin, UNIT_SIZE * 10); G_EventSpawnSound(playerMask, false, door, door->origin, door->noise); } } /* Update model orientation */ gi.SetInlineModelOrientation(door->model, door->origin, door->angles); AABB newAabb; gi.GetInlineModelAABB(door->model, newAabb); GridBox rerouteNewBox(newAabb); Com_DPrintf(DEBUG_GAME, "Server processed door movement.\n"); /* Update path finding table for the new location of the model */ G_RecalcRouting(door->model, rerouteOldBox); /* Update path finding table */ G_RecalcRouting(door->model, rerouteNewBox); if (activator && G_IsLivingActor(activator)) { /* Check if the player appears/perishes, seen from other teams. */ G_CheckVis(activator); /* Calc new vis for the activator. */ G_CheckVisTeamAll(activator->team, 0, activator); } return true; }