Exemple #1
0
/**
 * @sa CL_BiggestItem
 * @param[in] le The local entity (ET_ITEM) with the floor container
 */
void LE_PlaceItem (le_t* le)
{
	assert(LE_IsItem(le));

	/* search owners (there can be many, some of them dead) */
	le_t* actor = nullptr;
	while ((actor = LE_GetNextInUse(actor))) {
		if ((actor->type == ET_ACTOR || actor->type == ET_ACTOR2x2)
		 && VectorCompare(actor->pos, le->pos)) {
			if (le->getFloorContainer())
				actor->setFloor(le);
		}
	}

	/* the le is an ET_ITEM entity, this entity is there to render dropped items
	 * if there are no items in the floor container, this entity can be
	 * deactivated */
	Item* floorCont = le->getFloorContainer();
	if (floorCont) {
		const objDef_t* biggest = LE_BiggestItem(floorCont);
		le->model1 = cls.modelPool[biggest->idx];
		if (!le->model1)
			Com_Error(ERR_DROP, "Model for item %s is not precached in the cls.model_weapons array",
				biggest->id);
		Grid_PosToVec(cl.mapData->routing, le->fieldSize, le->pos, le->origin);
		VectorSubtract(le->origin, biggest->center, le->origin);
		le->angles[ROLL] = 90;
		/*le->angles[YAW] = 10*(int)(le->origin[0] + le->origin[1] + le->origin[2]) % 360; */
		le->origin[2] -= GROUND_DELTA;
	} else {
		/* If no items in floor inventory, don't draw this le - the container is
		 * maybe empty because an actor picked up the last items here */
		le->flags |= LE_REMOVE_NEXT_FRAME;
	}
}
Exemple #2
0
static inline void LE_GenerateInlineModelList (void)
{
	le_t* le = nullptr;
	int i = 0;

	while ((le = LE_GetNextInUse(le))) {
		if (le->model1 && le->inlineModelName[0] == '*')
			cl.leInlineModelList[i++] = le->inlineModelName;
	}
	cl.leInlineModelList[i] = nullptr;
}
Exemple #3
0
/**
 * @brief Searches a local entity on a given grid field
 * @param[in] pos The grid pos to search for an item of the given type
 */
le_t* LE_GetFromPos (const pos3_t pos)
{
	le_t* le = nullptr;

	while ((le = LE_GetNextInUse(le))) {
		if (VectorCompare(le->pos, pos))
			return le;
	}

	/* didn't find it */
	return nullptr;
}
/**
 * @brief Called whenever an entity disappears from view
 * @sa CL_EntAppear
 */
void CL_EntPerish (const eventRegister_t *self, struct dbuffer *msg)
{
	int		entnum;
	int		type;
	le_t	*le, *actor;

	NET_ReadFormat(msg, self->formatString, &entnum, &type);

	le = LE_Get(entnum);

	if (!le)
		LE_NotFoundWithTypeError(entnum, type);

	switch (le->type) {
	case ET_ITEM:
		cls.i.EmptyContainer(&cls.i, &le->i, INVDEF(csi.idFloor));

		/* search owners (there can be many, some of them dead) */
		actor = NULL;
		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");
				FLOOR(actor) = NULL;
			}
		}
		break;
	case ET_ACTOR:
	case ET_ACTOR2x2:
		cls.i.DestroyInventory(&cls.i, &le->i);
		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:
		CL_ParticleFree(le->ptl);
		le->ptl = NULL;
		break;
	case ET_BREAKABLE:
	case ET_DOOR:
	case ET_DOOR_SLIDING:
		break;
	default:
		break;
	}

	le->invis = qtrue;
	/* decrease the count of spotted aliens (also stunned) */
	cl.numEnemiesSpotted = CL_CountVisibleEnemies();
}
Exemple #5
0
/**
 * @brief Searches a local entity on a given grid field
 * @param[in] type Entity type
 * @param[in] pos The grid pos to search for an item of the given type
 */
le_t* LE_Find (entity_type_t type, const pos3_t pos)
{
	le_t* le = nullptr;

	while ((le = LE_GetNextInUse(le))) {
		if (le->type == type && VectorCompare(le->pos, pos))
			/* found the LE */
			return le;
	}

	/* didn't find it */
	return nullptr;
}
Exemple #6
0
/**
 * @sa CL_Frame
 */
void S_Frame (void)
{
    if (snd_init && snd_init->modified) {
        S_Restart_f();
        snd_init->modified = false;
    }

    if (!s_env.initialized)
        return;

    M_Frame();

    if (CL_OnBattlescape()) {
        int i;
        s_channel_t *ch;
        le_t *le;

        /* update right angle for stereo panning */
        VectorCopy(cl.cam.axis[AXIS_RIGHT], s_env.right);
        S_MumbleUpdate(cl.cam.camorg, cl.cam.axis[AXIS_FORWARD], cl.cam.axis[AXIS_RIGHT], cl.cam.axis[AXIS_UP]);

        /* update spatialization for current sounds */
        ch = s_env.channels;

        for (i = 0; i < MAX_CHANNELS; i++, ch++) {
            if (!ch->sample)
                continue;

            /* reset channel's count for loop samples */
            ch->count = 0;

            S_SpatializeChannel(ch);
        }

        /* ambient sounds */
        le = NULL;
        while ((le = LE_GetNextInUse(le))) {
            if (le->type == ET_SOUND) {
                s_sample_t *sample = S_GetSample(le->sampleIdx);
                int j;
                for (j = 0; j < MAX_CHANNELS; j++) {
                    if (s_env.channels[j].sample == sample)
                        break;
                }

                if (j == MAX_CHANNELS)
                    S_LoopSample(le->origin, sample, le->volume, le->attenuation);
            }
        }
    }
}
/**
 * @brief Counts visible enemies on the battlescape
 * @return The amount of visible enemies (from all the other teams)
 */
int CL_CountVisibleEnemies (void)
{
	le_t *le;
	int count;

	count = 0;
	le = NULL;
	while ((le = LE_GetNextInUse(le))) {
		if (LE_IsLivingAndVisibleActor(le) && le->team != cls.team && le->team != TEAM_CIVILIAN)
			count++;
	}

	return count;
}
Exemple #8
0
/**
 * @brief Collecting stunned aliens and alien bodies after the mission.
 * @param[in] aircraft Pointer to the aircraft with cargo.
 * @sa CL_ParseResults
 * @sa CL_GameAutoGo
 */
void AL_CollectingAliens (aircraft_t *aircraft)
{
	le_t *le = NULL;

	while ((le = LE_GetNextInUse(le))) {
		if (LE_IsActor(le) && LE_IsAlien(le)) {
			assert(le->teamDef);

			if (LE_IsStunned(le))
				AL_AddAlienTypeToAircraftCargo(aircraft, le->teamDef, 1, qfalse);
			else if (LE_IsDead(le))
				AL_AddAlienTypeToAircraftCargo(aircraft, le->teamDef, 1, qtrue);
		}
	}
}
Exemple #9
0
/**
 * @brief Searches all local entities for the one with the searched entnum
 * @param[in] entnum The entity number (server side)
 * @sa LE_Add
 */
le_t* LE_Get (int entnum)
{
	le_t* le = nullptr;

	if (entnum == SKIP_LOCAL_ENTITY)
		return nullptr;

	while ((le = LE_GetNextInUse(le))) {
		if (le->entnum == entnum)
			/* found the LE */
			return le;
	}

	/* didn't find it */
	return nullptr;
}
Exemple #10
0
/**
 * @brief Returns entities that have origins within a spherical area.
 * @param[in] from The entity to start the search from. @c nullptr will start from the beginning.
 * @param[in] org The origin that is the center of the circle.
 * @param[in] rad radius to search an edict in.
 * @param[in] type Type of local entity. @c ET_NULL to ignore the type.
 */
le_t* LE_FindRadius (le_t* from, const vec3_t org, float rad, entity_type_t type)
{
	le_t* le = from;

	while ((le = LE_GetNextInUse(le))) {
		if (type != ET_NULL && le->type != type)
			continue;
		vec3_t eorg;
		vec3_t leCenter;
		le->aabb.getCenter(leCenter);
		for (int j = 0; j < 3; j++)
			eorg[j] = org[j] - (le->origin[j] + leCenter[j]);
		if (VectorLength(eorg) > rad)
			continue;
		return le;
	}

	return nullptr;
}
Exemple #11
0
/**
 * @brief Clip against solid entities
 * @sa CL_Trace
 * @sa SV_ClipMoveToEntities
 */
static void CL_ClipMoveToLEs (MoveClipCL* clip)
{
	if (clip->trace.allsolid)
		return;

	le_t* le = nullptr;
	while ((le = LE_GetNextInUse(le))) {
		int tile = 0;

		if (!(le->contents & clip->contentmask))
			continue;
		if (le == clip->passle || le == clip->passle2)
			continue;

		vec3_t angles, shift;
		const int32_t headnode = CL_HullForEntity(le, &tile, shift, angles);
		assert(headnode < MAX_MAP_NODES);

		vec3_t origin;
		VectorCopy(le->origin, origin);

		trace_t trace = CM_HintedTransformedBoxTrace(cl.mapTiles->mapTiles[tile], clip->moveLine, clip->objBox,
				headnode, clip->contentmask, 0, origin, angles, shift, 1.0);

		if (trace.fraction < clip->trace.fraction) {
			/* make sure we keep a startsolid from a previous trace */
			const bool oldStart = clip->trace.startsolid;
			trace.le = le;
			clip->trace = trace;
			clip->trace.startsolid |= oldStart;
		/* if true, plane is not valid */
		} else if (trace.allsolid) {
			trace.le = le;
			clip->trace = trace;
		/* if true, the initial point was in a solid area */
		} else if (trace.startsolid) {
			trace.le = le;
			clip->trace.startsolid = true;
		}
	}
}
/**
 * @brief Searches a local entity at the given position.
 * @param[in] pos The grid position to search a local entity at
 * @param[in] includingStunned Also search for stunned actors if @c true.
 * @param[in] actor The current selected actor
 */
le_t* CL_BattlescapeSearchAtGridPos (const pos3_t pos, bool includingStunned, const le_t *actor)
{
	le_t *le;
	le_t *nonActor = NULL;

	/* search for an actor on this field */
	le = NULL;
	while ((le = LE_GetNextInUse(le))) {
		if (actor != NULL && le == actor->clientAction) {
			/* if the actor has a client action assigned and we click onto the actor,
			 * we will trigger this client action */
			if (VectorCompare(actor->pos, pos))
				nonActor = le;
		} else if (le != actor && LE_IsLivingAndVisibleActor(le) && (includingStunned || !LE_IsStunned(le)))
			switch (le->fieldSize) {
			case ACTOR_SIZE_NORMAL:
				if (VectorCompare(le->pos, pos))
					return le;
				break;
			case ACTOR_SIZE_2x2: {
				pos3_t actor2x2[3];

				VectorSet(actor2x2[0], le->pos[0] + 1, le->pos[1],     le->pos[2]);
				VectorSet(actor2x2[1], le->pos[0],     le->pos[1] + 1, le->pos[2]);
				VectorSet(actor2x2[2], le->pos[0] + 1, le->pos[1] + 1, le->pos[2]);
				if (VectorCompare(le->pos, pos)
				|| VectorCompare(actor2x2[0], pos)
				|| VectorCompare(actor2x2[1], pos)
				|| VectorCompare(actor2x2[2], pos))
					return le;
				break;
			}
			default:
				Com_Error(ERR_DROP, "Grid_MoveCalc: unknown actor-size: %i!", le->fieldSize);
		}
	}

	return nonActor;
}
Exemple #13
0
/**
 * @sa CMod_GetMapSize
 * @note we only need to handle the 2d plane and can ignore the z level
 * @param[in] node Node description of the radar
 */
void uiRadarNode::draw (uiNode_t* node)
{
	vec2_t pos;
	vec2_t screenPos;
#ifdef RADARSIZE_DEBUG
	int textposy = 40;
	static const vec4_t red = {1, 0, 0, 0.5};
#endif

	static const vec4_t backgroundColor = {0.0, 0.0, 0.0, 1};
	const float mapWidth = cl.mapData->mapBox.getWidthX();
	const float mapHeight = cl.mapData->mapBox.getWidthY();

	/** @todo use the same coef for x and y */
	const float mapCoefX = (float) node->box.size[0] / (float) mapWidth;
	const float mapCoefY = (float) node->box.size[1] / (float) mapHeight;

	if (cls.state != ca_active)
		return;

	UI_GetNodeAbsPos(node, pos);
	UI_GetNodeScreenPos(node, screenPos);
	R_CleanupDepthBuffer(pos[0], pos[1], node->box.size[0], node->box.size[1]);
	UI_DrawFill(pos[0], pos[1], mapWidth * mapCoefX, mapHeight * mapCoefY, backgroundColor);
#ifndef RADARSIZE_DEBUG
	UI_PushClipRect(screenPos[0], screenPos[1], node->box.size[0], node->box.size[1]);
#endif

	/* the cl struct is wiped with every new map */
	if (!cl.radarInitialized) {
		UI_InitRadar(node);
		cl.radarInitialized = true;
	}

	/* update context */
	radar.x = pos[0];
	radar.y = pos[1];
	radar.w = node->box.size[0];
	radar.h = node->box.size[1];
	if (radar.gridWidth < 6)
		radar.gridWidth = 6;
	if (radar.gridHeight < 6)
		radar.gridHeight = 6;

#ifdef RADARSIZE_DEBUG
	UI_DrawStringInBox("f_small", ALIGN_UL, 50, textposy, 500, 25, va("%fx%f %fx%f map", cl.mapData->mapBox.getMinX(), cl.mapData->mapBox.getMinY(), cl.mapData->getMaxX(), cl.mapData->getMaxY()));
	textposy += 25;
	UI_DrawStringInBox("f_small", ALIGN_UL, 50, textposy, 500, 25, va("%fx%f map", mapWidth, mapHeight));
	textposy += 25;
#endif

	/* draw background */
	for (int i = 0; i < radar.numImages; i++) {
		vec2_t imagePos;
		hudRadarImage_t* tile = &radar.images[i];
		int maxlevel = cl_worldlevel->integer;

		/* check the max level value for this map tile */
		if (maxlevel >= tile->maxlevel)
			maxlevel = tile->maxlevel - 1;
		assert(tile->path[maxlevel]);
		imagePos[0] = radar.x + mapCoefX * (tile->mapX - cl.mapData->mapBox.getMinX());
		imagePos[1] = radar.y + mapCoefY * (tile->mapY - cl.mapData->mapBox.getMinY());

		UI_DrawNormImageByName(false, imagePos[0], imagePos[1],
				mapCoefX * tile->mapWidth, mapCoefY * tile->mapHeight,
				0, 0, 0, 0, tile->path[maxlevel]);
#ifdef RADARSIZE_DEBUG
		UI_DrawStringInBox("f_small", ALIGN_UL, 50, textposy, 500, 25, va("%dx%d %dx%d %s", tile->x, tile->y, tile->width, tile->height, tile->path[maxlevel]));
		textposy += 25;
		UI_DrawStringInBox("f_small", ALIGN_UL, imagePos[0], imagePos[1], 500, 25, va("%dx%d", tile->gridX, tile->gridY));
#endif
	}

#ifdef RADARSIZE_DEBUG
	UI_DrawFill(pos[0], pos[1], 100.0f * mapCoefX, 100.0f * mapCoefY, red);
	UI_DrawFill(pos[0], pos[1], UNIT_SIZE * mapCoefX, UNIT_SIZE * mapCoefY, red);
#endif

	le_t* le = nullptr;
	while ((le = LE_GetNextInUse(le))) {
		vec3_t itempos;
		if (LE_IsInvisible(le))
			continue;

		/* convert to radar area coordinates */
		itempos[0] = pos[0] + (le->origin[0] - cl.mapData->mapBox.getMinX()) * mapCoefX;
		itempos[1] = pos[1] + (mapHeight - (le->origin[1] - cl.mapData->mapBox.getMinY())) * mapCoefY;

		switch (le->type) {
		case ET_ACTOR:
		case ET_ACTOR2x2:
			UI_RadarNodeDrawActor(le, itempos);
			break;
		case ET_ITEM:
			UI_RadarNodeDrawItem(le, itempos);
			break;
		default:
			break;
		}
#ifdef RADARSIZE_DEBUG
		UI_DrawStringInBox("f_small", ALIGN_UL, 50, textposy, 500, 25, va("%fx%f %dx%d actor", le->origin[0], le->origin[1], le->pos[0], le->pos[1]));
		textposy += 25;
		UI_DrawFill(itempos[0], itempos[1], UNIT_SIZE * mapCoefX, 1, red);
		UI_DrawFill(itempos[0], itempos[1], 1, UNIT_SIZE * mapCoefY, red);
#endif
	}

#ifndef RADARSIZE_DEBUG
	UI_PopClipRect();
#endif
}
Exemple #14
0
/**
 * @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);
}
Exemple #15
0
/**
 * @brief Call before entering a new level, or after vid_restart
 */
void CL_ViewLoadMedia (void)
{
	le_t* le;
	int i, max;
	float loadingPercent;

	CL_ViewUpdateRenderData();

	if (CL_GetConfigString(CS_TILES)[0] == '\0')
		return;					/* no map loaded */

	GAME_InitMissionBriefing(_(CL_GetConfigString(CS_MAPTITLE)));

	loadingPercent = 0;

	/* register models, pics, and skins */
	SCR_DrawLoading(loadingPercent);
	R_ModBeginLoading(CL_GetConfigString(CS_TILES), CL_GetConfigStringInteger(CS_LIGHTMAP),
			CL_GetConfigString(CS_POSITIONS), CL_GetConfigString(CS_NAME), CL_GetConfigString(CS_MAPZONE));
	CL_SpawnParseEntitystring();

	loadingPercent += 10.0f;
	SCR_DrawLoading(loadingPercent);

	LM_Register();
	CL_ParticleRegisterArt();

	for (i = 1, max = 0; i < MAX_MODELS && CL_GetConfigString(CS_MODELS + i)[0] != '\0'; i++)
		max++;

	max += csi.numODs;

	for (i = 1; i < MAX_MODELS; i++) {
		const char* name = CL_GetConfigString(CS_MODELS + i);
		if (name[0] == '\0')
			break;
		SCR_DrawLoading(loadingPercent);
		cl.model_draw[i] = R_FindModel(name);
		if (!cl.model_draw[i]) {
			Cmd_ExecuteString("fs_info");
			Com_Error(ERR_DROP, "Could not load model '%s'\n", name);
		}

		/* initialize clipping for bmodels */
		if (name[0] == '*')
			cl.model_clip[i] = CM_InlineModel(cl.mapTiles, name);
		else
			cl.model_clip[i] = nullptr;

		loadingPercent += 100.0f / (float)max;
	}

	/* update le model references */
	le = nullptr;
	while ((le = LE_GetNextInUse(le))) {
		if (le->modelnum1 > 0)
			le->model1 = LE_GetDrawModel(le->modelnum1);
		if (le->modelnum2 > 0)
			le->model2 = LE_GetDrawModel(le->modelnum2);
	}

	refdef.ready = true;

	/* waiting for EV_START */
	SCR_EndLoadingPlaque();
}