/** * @note Think function * @brief Change the actors animation to walking * @note See the *.anm files in the models dir */ void LET_StartPathMove (le_t* le) { /* center view (if wanted) */ if (!cls.isOurRound() && le->team != TEAM_CIVILIAN) LE_CenterView(le); /* initial animation or animation change */ R_AnimChange(&le->as, le->model1, LE_GetAnim("walk", le->right, le->left, le->state)); if (!le->as.change) Com_Printf("LET_StartPathMove: Could not change anim of le: %i, team: %i, pnum: %i\n", le->entnum, le->team, le->pnum); LE_SetThink(le, LET_PathMove); LE_ExecuteThink(le); }
/** * @sa CL_ActorAddToTeamList * @sa G_AppearPerishEvent * @sa CL_ActorAdd * @note EV_ACTOR_APPEAR */ void CL_ActorAppear (const eventRegister_t *self, struct dbuffer *msg) { le_t *le, *leResponsible; int entnum, entnumResponsible, modelnum1, modelnum2; int teamDefID = -1; /* check if the actor is already visible */ entnum = NET_ReadShort(msg); entnumResponsible = NET_ReadShort(msg); le = LE_Get(entnum); leResponsible = LE_Get(entnumResponsible); if (entnumResponsible != SKIP_LOCAL_ENTITY && !leResponsible) LE_NotFoundError(entnumResponsible); /* mission start - no actor is spawned yet - so create it */ if (!le) le = LE_Add(entnum); /* Locking should be unnecessary if CL_CheckDefault filters this call, since this event starts and * ends in this function only. Adding lock/unlock just to be sure. */ LE_Lock(le); /* maybe added via CL_ActorAdd before */ le->invis = false; /* get the info */ NET_ReadFormat(msg, self->formatString, &le->team, &teamDefID, &le->gender, &le->ucn, &le->pnum, &le->pos, &le->angle, &le->right, &le->left, &modelnum1, &modelnum2, &le->bodySkin, &le->headSkin, &le->state, &le->fieldSize, &le->maxTU, &le->maxMorale, &le->maxHP); if (teamDefID < 0 || teamDefID > csi.numTeamDefs) Com_Printf("CL_ActorAppear: Invalid teamDef index\n"); else le->teamDef = &csi.teamDef[teamDefID]; switch (le->fieldSize) { case ACTOR_SIZE_NORMAL: le->addFunc = CL_AddActor; le->type = ET_ACTOR; break; case ACTOR_SIZE_2x2: le->addFunc = CL_AddUGV; le->type = ET_ACTOR2x2; break; default: Com_Error(ERR_DROP, "Unknown fieldSize for le in CL_ActorAppear (EV_ACTOR_APPEAR)"); } le->modelnum1 = modelnum1; le->modelnum2 = modelnum2; le->model1 = LE_GetDrawModel(modelnum1); le->model2 = LE_GetDrawModel(modelnum2); Grid_PosToVec(cl.mapData->map, le->fieldSize, le->pos, le->origin); le->angles[YAW] = directionAngles[le->angle]; if (LE_IsDead(le) && !LE_IsStunned(le)) le->contents = CONTENTS_DEADACTOR; else le->contents = CONTENTS_ACTOR; VectorCopy(player_mins, le->mins); if (LE_IsDead(le)) VectorCopy(player_dead_maxs, le->maxs); else VectorCopy(player_maxs, le->maxs); LE_SetThink(le, LET_StartIdle); /* count spotted aliens (also stunned) */ cl.numEnemiesSpotted = CL_CountVisibleEnemies(); if (LE_IsLivingActor(le)) { if (cl.actTeam != cls.team) { /* center view (if wanted) */ LE_CenterView(le); } /* draw line of sight */ if (le->team != cls.team) { if (leResponsible) CL_DrawLineOfSight(leResponsible, le); /* message */ if (le->team != TEAM_CIVILIAN) { if (GAME_TeamIsKnown(le->teamDef)) { char tmpbuf[128]; Com_sprintf(tmpbuf, sizeof(tmpbuf), _("Enemy spotted: %s!"), _(le->teamDef->name)); HUD_DisplayMessage(tmpbuf); } else HUD_DisplayMessage(_("Unknown enemy spotted!")); } else HUD_DisplayMessage(_("Civilian spotted.")); /* update pathing as new actor could block path */ CL_ActorConditionalMoveCalc(leResponsible ? leResponsible : selActor); } } /* add team members to the actor list */ CL_ActorAddToTeamList(le); LE_Unlock(le); }
/** * @brief Called whenever an entity disappears from view * @sa CL_EntAppear */ void CL_EntPerish (const eventRegister_t* self, dbuffer* msg) { int entnum; int type; NET_ReadFormat(msg, self->formatString, &entnum, &type); le_t* le = LE_Get(entnum); if (!le) LE_NotFoundWithTypeError(entnum, type); le_t* actor = nullptr; switch (le->type) { case ET_ITEM: cls.i.emptyContainer(&le->inv, CID_FLOOR); /* search owners (there can be many, some of them dead) */ while ((actor = LE_GetNextInUse(actor))) { if ((actor->type == ET_ACTOR || actor->type == ET_ACTOR2x2) && VectorCompare(actor->pos, le->pos)) { Com_DPrintf(DEBUG_CLIENT, "CL_EntPerish: le of type ET_ITEM hidden\n"); actor->resetFloor(); } } break; case ET_ACTOR: case ET_ACTOR2x2: if (!cls.isOurRound() && le->team != TEAM_CIVILIAN) LE_CenterView(le); cls.i.destroyInventory(&le->inv); if (le->ptl) { CL_ParticleFree(le->ptl); le->ptl = nullptr; } /* Clear anim data to prevent actor "jumping" to new animation when it reappears, or worse animation issues. */ OBJZERO(le->as); break; #ifdef DEBUG case ET_ACTORHIDDEN: Com_DPrintf(DEBUG_CLIENT, "CL_EntPerish: It should not happen that we perish a hidden actor\n"); return; #endif case ET_PARTICLE: if (le->ptl) { CL_ParticleFree(le->ptl); le->ptl = nullptr; } else { Com_Printf("CL_EntPerish: Particle is nullptr for entnum %i!\n", entnum); } break; case ET_BREAKABLE: case ET_DOOR: case ET_DOOR_SLIDING: break; default: break; } le->flags |= LE_INVISIBLE; /* decrease the count of spotted aliens (also stunned) */ cl.numEnemiesSpotted = CL_CountVisibleEnemies(); Cvar_SetValue("mn_numaliensspotted", cl.numEnemiesSpotted); }