Beispiel #1
0
/**
 * Exponentially decreases momentum.
 */
void G_DecreaseMomentum()
{
	int          team;
	float        amount;

	static float decreaseFactor = 1.0f, lastMomentumHalfLife = 0.0f;
	static int   nextCalculation = 0;

	if ( level.time < nextCalculation )
	{
		return;
	}

	if ( g_momentumHalfLife.value <= 0.0f )
	{
		return;
	}

	// only calculate decreaseFactor if the server configuration changed
	if ( lastMomentumHalfLife != g_momentumHalfLife.value )
	{
		// ln(2) ~= 0.6931472
		decreaseFactor = exp( ( -0.6931472f / ( ( 60000.0f / DECREASE_MOMENTUM_PERIOD ) *
		                                        g_momentumHalfLife.value ) ) );

		lastMomentumHalfLife = g_momentumHalfLife.value;
	}

	// decrease momentum
	for ( team = TEAM_NONE + 1; team < NUM_TEAMS; team++ )
	{
		amount = level.team[ team ].momentum * ( decreaseFactor - 1.0f );

		level.team[ team ].momentum += amount;

		// notify legacy stage sensors
		NotifyLegacyStageSensors( (team_t) team, amount );
	}

	MomentumChanged();

	nextCalculation = level.time + DECREASE_MOMENTUM_PERIOD;
}
Beispiel #2
0
/**
 * Has to be called after the last G_AddMomentum*Step step.
 */
void G_AddMomentumEnd() {
    MomentumChanged();
}
Beispiel #3
0
/**
 * Awards momentum to a team.
 *
 * Will notify the client hwo earned it if given, otherwise the whole team, with
 *an event.
 */
static float AddMomentum(momentum_t type, team_t team, float amount, gentity_t* source, bool skipChangeHook) {
    gentity_t* event = nullptr;
    gclient_t* client;
    char* clientName;

    if (team <= TEAM_NONE || team >= NUM_TEAMS) {
        return 0.0f;
    }

    // apply modifier
    amount *= MomentumMod(type);

    // limit a team's total
    if (level.team[team].momentum + amount > MOMENTUM_MAX) {
        amount = MOMENTUM_MAX - level.team[team].momentum;
    }

    if (amount != 0.0f) {
        // add momentum to team
        level.team[team].momentum += amount;

        // run change hook if requested
        if (!skipChangeHook) {
            MomentumChanged();
        }

        // notify source
        if (source) {
            client = source->client;

            if (client && client->pers.team == team) {
                event = G_NewTempEntity(client->ps.origin, EV_MOMENTUM);
                event->r.svFlags = SVF_SINGLECLIENT;
                event->r.singleClient = client->ps.clientNum;
            }
        } else {
            event = G_NewTempEntity(vec3_origin, EV_MOMENTUM);
            event->r.svFlags = (SVF_BROADCAST | SVF_CLIENTMASK);
            G_TeamToClientmask(team, &(event->r.loMask), &(event->r.hiMask));
        }
        if (event) {
            // TODO: Use more bits for momentum value
            event->s.eventParm = 0;
            event->s.otherEntityNum = 0;
            event->s.otherEntityNum2 = (int) (fabs(amount) * 10.0f + 0.5f);
            event->s.groundEntityNum = amount < 0.0f ? true : false;
        }

        // notify legacy stage sensors
        NotifyLegacyStageSensors(team, amount);
    }

    if (g_debugMomentum.integer > 0) {
        if (source && source->client) {
            clientName = source->client->pers.netname;
        } else {
            clientName = "no source";
        }

        Com_Printf("Momentum: %.2f to %s (%s by %s for %s)\n", amount, BG_TeamNamePlural(team), amount < 0.0f ? "lost" : "earned", clientName, MomentumTypeToReason(type));
    }

    return amount;
}