/** * @brief Searches a free spawning point for a given actor size and turns it into an actor * @param[in] player The player to get the free spawn points for * @param[in] actorSize The actor size to get a spawning point for * @return An actor edict or @c NULL if no free spawning point was found */ edict_t* G_ClientGetFreeSpawnPointForActorSize (const player_t *player, const actorSizeEnum_t actorSize) { edict_t *ent; if (actorSize == ACTOR_SIZE_NORMAL) { /* Find valid actor spawn fields for this player. */ ent = G_ClientGetFreeSpawnPoint(player, ET_ACTORSPAWN); if (ent) { edict_t *copy = G_EdictDuplicate(ent); if (copy != NULL) copy->type = ET_ACTOR; ent = copy; } } else if (actorSize == ACTOR_SIZE_2x2) { /* Find valid actor spawn fields for this player. */ ent = G_ClientGetFreeSpawnPoint(player, ET_ACTOR2x2SPAWN); if (ent) { edict_t *copy = G_EdictDuplicate(ent); if (copy != NULL) { copy->type = ET_ACTOR2x2; copy->morale = 100; } ent = copy; } } else { gi.Error("G_ClientGetFreeSpawnPointForActorSize: unknown fieldSize for actor edict (actorSize: %i)\n", actorSize); } if (!ent) return NULL; level.num_spawned[ent->team]++; ent->pnum = player->num; ent->chr.fieldSize = actorSize; ent->fieldSize = ent->chr.fieldSize; ent->flags |= FL_DESTROYABLE; G_VisFlagsReset(ent); gi.LinkEdict(ent); if (ent->spawnflags & STATE_CROUCHED) { ent->think = G_ThinkActorGoCrouch; ent->nextthink = 1; } if (ent->spawnflags & STATE_STUN) { if (ent->spawnflags & STATE_DEAD) ent->HP = 0; ent->think = G_ThinkActorDieAfterSpawn; ent->nextthink = 1; } G_ActorModifyCounters(NULL, ent, 1, 0, 0); G_ReactionFireTargetsCreate(ent); return ent; }
static bool G_ActorDie (Edict* ent, const Edict* attacker) { const bool stunned = G_IsStunned(ent); G_RemoveStunned(ent); if (G_IsDead(ent)) return false; G_SetState(ent, 1 + rand() % MAX_DEATH); G_ActorSetMaxs(ent); if (stunned) { G_ActorModifyCounters(attacker, ent, 0, 1, 0); G_ActorModifyCounters(ent->link, ent, 0, 0, -1); } else { G_ActorModifyCounters(attacker, ent, -1, 1, 0); } return true; }
static bool G_ActorStun (Edict* ent, const Edict* attacker) { /* already dead or stunned? */ if (G_IsDead(ent)) return false; /* no other state should be set here */ ent->state = STATE_STUN; G_ActorSetMaxs(ent); ent->link = attacker; G_ActorModifyCounters(attacker, ent, -1, 0, 1); return true; }
static void G_ActorRevitalise (Edict* ent) { if (G_IsStunned(ent)) { G_RemoveStunned(ent); /** @todo have a look at the morale value of * the ent and maybe get into rage or panic? */ G_ActorModifyCounters(ent->link, ent, 1, 0, -1); G_GetFloorItems(ent); } G_ActorSetMaxs(ent); /* check if the player appears/perishes, seen from other teams */ G_CheckVis(ent); /* calc new vis for this player */ G_CheckVisTeamAll(ent->team, 0, ent); G_PrintStats("%s is revitalized.", ent->chr.name); }