Beispiel #1
0
static void G_StateChange_f (void)
{
    if (gi.Cmd_Argc() < 3) {
        gi.DPrintf("Usage: %s <entnum> <state>\n States are: panic, rage, shaken", gi.Cmd_Argv(0));
        return;
    }

    const int entnum = atoi(gi.Cmd_Argv(1));
    edict_t *e = G_EdictsGetByNum(entnum);
    if (e == NULL)
        return;

    const char *state = gi.Cmd_Argv(2);
    if (Q_strcasecmp(state, "panic")) {
        e->morale = mor_panic->integer / 2;
    } else if (Q_strcasecmp(state, "shaken")) {
        e->morale = mor_shaken->integer / 2;
    } else if (Q_strcasecmp(state, "rage")) {
        e->morale = m_rage->integer / 2;
    } else {
        e->morale = 0;
    }

    G_MoraleBehaviour(e->team);
}
Beispiel #2
0
static void G_UseEdict_f (void)
{
    edict_t *e;
    int i;

    if (gi.Cmd_Argc() < 2) {
        gi.DPrintf("Usage: %s <entnum>\n", gi.Cmd_Argv(0));
        return;
    }

    i = atoi(gi.Cmd_Argv(1));
    if (!G_EdictsIsValidNum(i)) {
        gi.DPrintf("No entity with number %i\n", i);
        return;
    }

    e = G_EdictsGetByNum(i);
    if (!e->use) {
        gi.DPrintf("No use function for entity %s\n", e->classname);
        return;
    }

    gi.DPrintf("Call use function for %s\n", e->classname);
    e->use(e, NULL);
}
Beispiel #3
0
static void G_TouchEdict_f (void)
{
    edict_t *e, *ent;
    int i;

    if (gi.Cmd_Argc() < 2) {
        gi.DPrintf("Usage: %s <entnum>\n", gi.Cmd_Argv(0));
        return;
    }

    i = atoi(gi.Cmd_Argv(1));
    if (!G_EdictsIsValidNum(i))
        return;

    e = G_EdictsGetByNum(i);
    if (!e->touch) {
        gi.DPrintf("No touch function for entity %s\n", e->classname);
        return;
    }

    ent = G_EdictsGetNextLivingActor(NULL);
    if (!ent)
        return;	/* didn't find any */

    gi.DPrintf("Call touch function for %s\n", e->classname);
    e->touch(e, ent);
}
Beispiel #4
0
void ReactionFireTargets::notifyClientOnShot (const Edict* target, int tusTarget)
{
	for (int i = 0; i < MAX_RF_DATA; i++) {
		ReactionFireTargetList* rfts = &rfData[i];
		if (rfts->entnum == RF_NO_ENTNUM)
			continue;
		const Edict* shooter = G_EdictsGetByNum(rfts->entnum);
		for (int j = 0; j < rfts->count; j++) {
			ReactionFireTarget& t = rfts->targets[j];
			if (t.target != target)
				continue;
			const int tus = std::max(0, target->TU - tusTarget - t.triggerTUs);
			G_EventReactionFireTargetUpdate(*shooter, *target, tus, MAX_ROUTE);
		}
	}
}
Beispiel #5
0
void ReactionFireTargets::notifyClientMove (const Edict* target, int step, bool startMove)
{
	for (int i = 0; i < MAX_RF_DATA; i++) {
		ReactionFireTargetList* rfts = &rfData[i];
		if (rfts->entnum == RF_NO_ENTNUM)
			continue;
		const Edict* shooter = G_EdictsGetByNum(rfts->entnum);
		for (int j = 0; j < rfts->count; j++) {
			if (rfts->targets[j].target != target)
				continue;
			if (startMove) {
				const int tus = target->TU - rfts->targets[j].triggerTUs;
				G_EventReactionFireAddTarget(*shooter, *target, tus, step);
			} else {
				G_EventReactionFireRemoveTarget(*shooter, *target, step);
			}
		}
	}
}
Beispiel #6
0
/**
 * @brief Do the shooting
 * @param ent The entity that is doing the shooting
 * @param teamMask the vis mask to determine the clients from this event is send to
 * @param fd The firedefinition to use for the shoot
 * @param firstShoot Is this the first shoot
 * @param shootType The type of the shoot
 * @param flags Define some flags in a bitmask: @c SF_BODY, @c SF_IMPACT, @c SF_BOUNCING and @c SF_BOUNCING
 * @param trace The trace what was used to determine whether this shot has hit something
 * @param from The position the entity shoots from
 * @param impact The impact world vector for the shot
 */
void G_EventShoot (const Edict& ent, teammask_t teamMask, const fireDef_t* fd, bool firstShoot, shoot_types_t shootType, int flags, const trace_t* trace, const vec3_t from, const vec3_t impact)
{
	const Edict* targetEdict = G_EdictsGetByNum(trace->entNum);	/* the ent possibly hit by the trace */

	G_EventAdd(G_VisToPM(teamMask), EV_ACTOR_SHOOT, ent.number);
	if (targetEdict && G_IsBreakable(targetEdict))
		gi.WriteShort(targetEdict->number);
	else
		gi.WriteShort(SKIP_LOCAL_ENTITY);
	gi.WriteByte(firstShoot ? 1 : 0);
	gi.WriteShort(fd->obj->idx);
	gi.WriteByte(fd->weapFdsIdx);
	gi.WriteByte(fd->fdIdx);
	gi.WriteByte(shootType);
	gi.WriteByte(flags);
	gi.WriteByte(trace->contentFlags);
	gi.WritePos(from);
	gi.WritePos(impact);
	gi.WriteDir(trace->plane.normal);
	G_EventEnd();
}
Beispiel #7
0
static void G_DestroyEdict_f (void)
{
    edict_t *e;
    int i;

    if (gi.Cmd_Argc() < 2) {
        gi.DPrintf("Usage: %s <entnum>\n", gi.Cmd_Argv(0));
        return;
    }

    i = atoi(gi.Cmd_Argv(1));
    if (!G_EdictsIsValidNum(i))
        return;

    e = G_EdictsGetByNum(i);
    if (!e->destroy) {
        gi.DPrintf("No destroy function for entity %s\n", e->classname);
        return;
    }

    gi.DPrintf("Call destroy function for %s\n", e->classname);
    e->destroy(e);
}
Beispiel #8
0
/**
 * @brief The client sent us a message that he did something. We now execute the related function(s) and notify him if necessary.
 * @param[in] player The player to execute the action for (the actor belongs to this player)
 * @note a client action will also send the server side edict number to determine the actor
 */
int G_ClientAction (player_t * player)
{
	player_action_t action;
	int num;
	pos3_t pos;
	int i;
	fireDefIndex_t firemode;
	int from, fx, fy, to, tx, ty;
	actorHands_t hand;
	int fmIdx, objIdx;
	int resCrouch, resShot;
	edict_t *ent;
	const char *format;

	/* read the header */
	action = (player_action_t)gi.ReadByte();
	num = gi.ReadShort();

	ent = G_EdictsGetByNum(num);
	if (ent == NULL)
		return action;

	format = pa_format[action];

	switch (action) {
	case PA_NULL:
		/* do nothing on a null action */
		break;

	case PA_TURN:
		gi.ReadFormat(format, &i);
		G_ClientTurn(player, ent, (dvec_t) i);
		break;

	case PA_MOVE:
		gi.ReadFormat(format, &pos);
		G_ClientMove(player, player->pers.team, ent, pos);
		break;

	case PA_STATE:
		gi.ReadFormat(format, &i);
		G_ClientStateChange(player, ent, i, true);
		break;

	case PA_SHOOT:
		gi.ReadFormat(format, &pos, &i, &firemode, &from);
		G_ClientShoot(player, ent, pos, i, firemode, NULL, true, from);
		break;

	case PA_INVMOVE:
		gi.ReadFormat(format, &from, &fx, &fy, &to, &tx, &ty);

		if (from < 0 || from >= gi.csi->numIDs || to < 0 || to >= gi.csi->numIDs) {
			gi.DPrintf("G_ClientAction: PA_INVMOVE Container index out of range. (from: %i, to: %i)\n", from, to);
		} else {
			const invDef_t *fromPtr = INVDEF(from);
			const invDef_t *toPtr = INVDEF(to);
			invList_t *fromItem = INVSH_SearchInInventory(&ent->chr.i, fromPtr, fx, fy);
			if (fromItem)
				G_ActorInvMove(ent, fromPtr, fromItem, toPtr, tx, ty, true);
		}
		break;

	case PA_USE:
		if (ent->clientAction) {
			edict_t *actionEnt;

			/* read the door the client wants to open */
			gi.ReadFormat(format, &i);

			/* get the door edict */
			actionEnt = G_EdictsGetByNum(i);

			/* maybe the door is no longer 'alive' because it was destroyed */
			if (actionEnt && ent->clientAction == actionEnt) {
				if (G_IsDoor(actionEnt)) {
					G_ActorUseDoor(ent, actionEnt);
				}
			}
		}
		break;

	case PA_REACT_SELECT:
		gi.ReadFormat(format, &hand, &fmIdx, &objIdx);
		G_ReactionFireSettingsUpdate(ent, fmIdx, hand, INVSH_GetItemByIDX(objIdx));
		break;

	case PA_RESERVE_STATE:
		gi.ReadFormat(format, &resShot, &resCrouch);

		G_ActorReserveTUs(ent, ent->chr.reservedTus.reaction, resShot, resCrouch);
		break;

	default:
		gi.Error("G_ClientAction: Unknown action!\n");
	}
	return action;
}