AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Zombie:Reloaded (https://forums.alliedmods.net/forumdisplay.php?f=132)
-   -   CS:GO Z:R fixes and workarounds (https://forums.alliedmods.net/showthread.php?t=244695)

Morell 07-22-2014 11:31

CS:GO Z:R fixes and workarounds
 
3 Attachment(s)
After dropping our CS:GO server months ago, we decided to move back to it. We have been trying to find a fix/workaround that lets us have a decent knockback for CS:GO. The workaround isn't equal to what you'd be expecting if you had only played CS:S' zombie mods, but it is enough to be enjoyable. It is based (we cooperated with mappers to get it) on setting the basevelocity field when hit, which lets you have a subtle knockback/push while on the ground (it lets a player hold a zombie by himself alone, which is enough for us). As seen on CS:GO, you'll get a normal knockback while on the air.

knockback.inc
Code:

/**
 * Minimum upwards boost that is required to push zombies off the ground.
 */
#define CSGO_KNOCKBACK_BOOST        251.0
#define CSGO_KNOCKBACK_BOOST_MAX    350.0

/** Client has been hurt.
 *
 * @param client        The client index. (zombie)
 * @param attacker      The attacker index. (human)
 * @param weapon        The weapon used.
 * @param hitgroup      Hitgroup attacker has damaged.
 * @param dmg_health    Damage done.
 */
KnockbackOnClientHurt(client, attacker, const String:weapon[], hitgroup, dmg_health)
{
    // If attacker is invalid, then stop.
    if (!ZRIsClientValid(attacker))
    {
        return;
    }
   
    // Client is a human, then stop.
    if (InfectIsClientHuman(client))
    {
        return;
    }
   
    // If attacker is a zombie, then stop.
    if (InfectIsClientInfected(attacker))
    {
        return;
    }
   
    // Block knock back if an immunity mode is handling this.
    if (ImmunityOnClientKnockBack(client))
    {
        return;
    }
   
    // Get zombie knockback value.
    new Float:knockback = ClassGetKnockback(client);
   
    new Float:clientloc[3];
    new Float:attackerloc[3];
   
    GetClientAbsOrigin(client, clientloc);
   
    // Check if a grenade was thrown.
    if (StrEqual(weapon, "hegrenade"))
    {
        // Get the location of the grenade.
        if (KnockbackFindExplodingGrenade(attackerloc) == -1)
        {
            // If the grenade wasn't found, then stop.
            return;
        }
    }
    else
    {
        // Get attackers eye position.
        GetClientEyePosition(attacker, attackerloc);
       
        // Get attackers eye angles.
        new Float:attackerang[3];
        GetClientEyeAngles(attacker, attackerang);
       
        // Calculate knockback end-vector.
        TR_TraceRayFilter(attackerloc, attackerang, MASK_ALL, RayType_Infinite, KnockbackTRFilter);
        TR_GetEndPosition(clientloc);
    }
   
    new bool:weapons = GetConVarBool(g_hCvarsList[CVAR_WEAPONS]);
    if (weapons)
    {
        new weaponindex = WeaponsNameToIndex(weapon);
        if (weaponindex != -1)
        {
            // Apply weapon knockback multiplier.
            knockback *= WeaponsGetKnockback(weaponindex);
        }
    }
   
    new bool:hitgroups = GetConVarBool(g_hCvarsList[CVAR_HITGROUPS]);
    if (hitgroups)
    {
        new hitgroupindex = HitgroupToIndex(hitgroup);
        if (hitgroupindex != -1)
        {
            // Apply hitgroup knockback multiplier.
            knockback *= HitgroupsGetKnockback(hitgroupindex);
        }
    }
   
    // Apply damage knockback multiplier.
    knockback *= float(dmg_health);
       
        knockback *= 7.5;
   
    // Apply knockback.
    KnockbackSetVelocity(client, attackerloc, clientloc, knockback);
}

/**
 * Sets velocity on a player.
 * 
 * @param client        The client index.
 * @param startpoint    The starting coordinate to push from.
 * @param endpoint      The ending coordinate to push towards.
 * @param magnitude    Magnitude of the push.
 */ 
KnockbackSetVelocity(client, const Float:startpoint[3], const Float:endpoint[3], Float:magnitude)
{
    // Create vector from the given starting and ending points.
    new Float:vector[3];
    MakeVectorFromPoints(startpoint, endpoint, vector);
 
    // Normalize the vector
    new Float:normal = GetVectorLength(vector);
    vector[0] /= normal;
    vector[1] /= normal;
    vector[2] /= normal;
 
    // Only apply knockback if the vector has a reasonable length (this avoids null vectors)
    if(normal>0.001)
    {
        // If we are touching the ground (with a threshold) we get a weaker Z-knockback
        // Perhaps this could be removed to suit your needs...
        if((GetClientDistanceToGround(client) > -1.0) && (GetClientDistanceToGround(client) < 1.0))
        {
                // This reduces the obnoxiousness of knockback on zombies that try to jump a crate
                // I'd recommend each server owner to tune to their specific needs.
                // It converges pretty fast, so it shouldn't be troublesome at all.
                while(vector[2]*magnitude > 64)
                {
                        magnitude/=2;
                }
        }
        // Otherwise we apply knockback with a cap
        // (256 is a good value because it's the breaking point for basevelocity to have an effect vertically, so it will push but not too much)
        else
        {
                if(magnitude > 256.0)
                {
                        magnitude = 256.0;
                }
        }
        // Apply the magnitude by scaling the vector (multiplying each of its components).
        ScaleVector(vector, magnitude);
               
        // Add the given vector to the client's current velocity.
        // We use the basevelocity (velocity for movement in vehicles/given by other forces) for that
        new g_iBaseVelocityOffset = FindSendPropOffs("CBasePlayer","m_vecBaseVelocity");
        SetEntDataVector(client, g_iBaseVelocityOffset, vector, true);
    }
}

/**
 * Trace Ray forward, used as a filter to continue tracing if told so. (See sdktools_trace.inc)
 * 
 * @param entity        The entity index.
 * @param contentsMask  The contents mask.
 * @return              True to allow hit, false to continue tracing.
 */
public bool:KnockbackTRFilter(entity, contentsMask)
{
    // If entity is a player, continue tracing.
    if (entity > 0 && entity < MAXPLAYERS)
    {
        return false;
    }
   
    // Allow hit.
    return true;
}

/**
 * Find the location of an exploding grenade (currently inflicting damage in player_hurt).
 * 
 * @param heLoc    The location of the exploding grenade.
 * @return          The entity index of the grenade.
 */ 
KnockbackFindExplodingGrenade(Float:heLoc[3])
{
    decl String:classname[64];
   
    // Find max entities and loop through all of them.
    new maxentities = GetMaxEntities();
    for (new x = MaxClients; x <= maxentities; x++)
    {
        // If entity is invalid, then stop.
        if (!IsValidEdict(x))
        {
            continue;
        }
       
        // If entity isn't a grenade, then stop.
        GetEdictClassname(x, classname, sizeof(classname));
        if (!StrEqual(classname, "hegrenade_projectile", false))
        {
            continue;
        }
       
        // If m_takedamage is set to 0, we found our grenade.
        new takedamage = GetEntProp(x, Prop_Data, "m_takedamage");
        if (takedamage == 0)
        {
            // Return its location.
            GetEntPropVector(x, Prop_Send, "m_vecOrigin", heLoc);
           
            // Return its entity index.
            return x;
        }
    }
   
    // Didn't find the grenade.
    return -1;
}

stock Float:GetClientDistanceToGround(client)
{
        new Float:distance = 0.0;
    // Player is already standing on the ground?
    if(GetEntPropEnt(client, Prop_Send, "m_hGroundEntity") == 0)
        {
                distance = 0.0;
                return distance;
        }
       
    new Float:fOrigin[3], Float:fGround[3];
    GetClientAbsOrigin(client, fOrigin);
   
    fOrigin[2] += 10.0;
   
    TR_TraceRayFilter(fOrigin, Float:{90.0,0.0,0.0}, MASK_PLAYERSOLID, RayType_Infinite, TraceRayNoPlayers, client);
    if (TR_DidHit())
    {
        TR_GetEndPosition(fGround);
        fOrigin[2] -= 10.0;
               
        distance = GetVectorDistance(fOrigin, fGround);
        return distance;
    }
    return distance;
}

public bool:TraceRayNoPlayers(entity, mask, any:data)
{
    if(entity == data || (entity >= 1 && entity <= MaxClients))
    {
        return false;
    }
    return true;
}

To handle this and make it more enjoyable, we figured out we could depend on subtle ground knockback plus extra vertical knockback (to produce 'jumps') provided by some weapons. We are publishing our vertical knockback for grenades too in case anyone wants a similar system. On the server, we have extended it for a few other weapons (knives, for example, and the awp). We thought about forcing a vertical knockback if on the ground (as you can see on the code), but we found that to be annoying (despite other communities using it).

Code:

#include <sourcemod>
#include <sdktools>
#include <sdkhooks>
#pragma semicolon 1

new Handle:g_Cvar_MaxZKnock = INVALID_HANDLE;
new Handle:g_Cvar_HeKnock = INVALID_HANDLE;

public Plugin:myinfo ={
        name = "Z:R Grenade Boost",
        author = "Marica Stevens",
        description = "Pushes zombies upwards when hit by a grenade.",
        version = "1.0.0",
        url = "http://maricascripters.com"
};

public OnPluginStart()
{
        g_Cvar_MaxZKnock = CreateConVar("sm_max_zknock", "32.0", "Knock in Z");
        g_Cvar_HeKnock = CreateConVar("sm_he_knock", "320.0", "Max Knock in Z");
        HookEvent("player_hurt", Event_HandleNadeDamage);
}

public OnPluginEnd()
{       
        UnhookEvent("player_hurt", Event_HandleNadeDamage);
}

public Event_HandleNadeDamage(Handle:event, const String:name[], bool:dontBroadcast)
{
        new clientid = GetEventInt(event, "userid");
        new client = GetClientOfUserId(clientid);
        new damage = GetEventInt(event,"dmg_health");
        decl String:weapon[32];
        GetEventString(event, "weapon", weapon, sizeof(weapon));
        if(GetClientTeam(client)==2 && StrEqual("hegrenade", weapon))
        {
                new Float:vector[3];
                vector[0] = 0.0;
                vector[1] = 0.0;
                vector[2] = GetConVarFloat(g_Cvar_HeKnock)*damage;
               
                if(vector[2]> GetConVarFloat(g_Cvar_MaxZKnock))
                {
                        vector[2] = GetConVarFloat(g_Cvar_MaxZKnock);
                }
                new g_iBaseVelocityOffset = FindSendPropOffs("CBasePlayer","m_vecBaseVelocity");
                SetEntDataVector(client, g_iBaseVelocityOffset, vector, true);
        }
}

Finally, to address the problem with zombies spawning as classes, we've tried to perfect the 'fix' (which didn't feel like enough to us) that Franc1sco made. We're sure that he probably updated his own, but seeing how it wasn't updated we're publishing ours.

Code:

#include <sourcemod>
#include <sdktools>
#undef REQUIRE_PLUGIN
#include <zombiereloaded>

new zombie1, zombie2, zombie3;

public Plugin:myinfo =
{
        name = "ZR Class Fix",
        author = "Mapeadores",
        description = "Class Fix (Franug plugin modification)",
        version = "1.5",
        url = "http://Mapeadores.com/"
};

public OnPluginStart()
{
        //Edit this with your zombie classes
        zombie1 = ZR_GetClassByName("Clasico");
        zombie2 = ZR_GetClassByName("Zombie Rapido");
        zombie3 = ZR_GetClassByName("Zombie Resistente");
}

public ZR_OnClientInfected(client, attacker, bool:motherInfect, bool:respawnOverride, bool:respawn)
{
        new vida = GetClientHealth(client);
        if(vida < 300)
        {
                CreateTimer(0.5, TimerAsegurarClase, client, TIMER_FLAG_NO_MAPCHANGE);
        }
}

public Action:TimerAsegurarClase(Handle:timer, any:client)
{
        AsegurarClaseDefault(client);
}

public AsegurarClaseDefault(client)
{
        SetEntityHealth(client, 5000);
        new randomnum = GetRandomInt(0, 2);
        switch(randomnum)
        {
                case 0:
                {
                        SetEntityModel(client, "models/player/mapeadores/morell/zh/zh3fix.mdl");
                        ZR_SelectClientClass(client, zombie3, true, true);
                }
                case 1:
                {
                        SetEntityModel(client, "models/player/mapeadores/kaem/zh/zh1fix.mdl");
                        ZR_SelectClientClass(client, zombie1, true, true);
                }
                case 2:
                {
                        SetEntityModel(client, "models/player/mapeadores/kaem/zh/zh2fix.mdl");
                        ZR_SelectClientClass(client, zombie2, true, true);
                }
        }
}

This plugin is a sample from our server. If you have seen Franc1sco's plugin you'll notice that it hasn't changed much, the only difference is that the plugin selects a valid class for a player so that this round (if possible) or next he gets a real zombie class. You'd need to adjust it to your settings by adding more classes following the style (we thought of making a nicer plugin but ended up slacking, sorry about that).

Those plugins, fixes and workarounds aren't optimal, probably, but seeing how the community doesn't seem to help, we thought that by adding our little grain of sand perhaps others will eventually join us and help the mod develop as a whole with interests aside.

On a different matter, some mappers have been porting maps with us being the test subjects. The mappers will eventually publish their ports in some sort of way, as they're following a set of porting rules to ensure that the ports have a minimal filesize while adapting the looks of the maps to the new engine. We have seen that some communities (shockingly, those that seem to rarely contribute or, rather, try to mock others whilst saying they've addressed issues) have 'stolen' those maps while they are still in the process of being perfected (and some even said they ported the maps themselves, which is rather bothersome). We'd value that, for some time, you stepped out and didn't use '_p' map ports until we have a big enough batch for everybody to use.

ATTACHED FIX WITH JARGON ZR FIXES: https://forums.alliedmods.net/showthread.php?t=200527

Pan32 07-22-2014 11:58

Re: CS:GO Z:R fixes and workarounds
 
1 Attachment(s)
Since class fixes requires zr to compile, ill just leave the compiled smx here. Please take note that this compile is using Morell's playerclasses config.

Thank you Morell!

Cook13s 07-22-2014 12:14

Re: CS:GO Z:R fixes and workarounds
 
As for the mappers thing, that sucks, not cool. It should be the author porting, or the guys trying to port re-making it themselves and crediting the original author. A veteran zombie mod mapper and I will be trying to port (his own) and create new maps, of course that is if we manage to get our server running.

bebe9b 07-22-2014 12:51

Re: CS:GO Z:R fixes and workarounds
 
Hi, how can I make the icon appear knife??
thx

Franc1sco 07-22-2014 14:56

Re: CS:GO Z:R fixes and workarounds
 
The class bug is a thing that now rarely occur so I dont update it more because I thought that are already fixed, I dont update the plugin, I dont know why you say that yes

Anyway, if bug continue I will make a new version more advanced because your code have errors like dont check if the player are ingame after CreateTimer and I can do more improvements

Btw, I currently have vacations, this weekend I will see it :3

Morell 07-22-2014 15:57

Re: CS:GO Z:R fixes and workarounds
 
Quote:

Originally Posted by bebe9b (Post 2171922)
Hi, how can I make the icon appear knife??
thx

Change this in zr/infect.inc:
Code:

SetEventString(event, "weapon", "zombie_claws_of_death");
for:
Code:

SetEventString(event, "weapon", "knife"); (or other knife)

bebe9b 07-22-2014 16:17

Re: CS:GO Z:R fixes and workarounds
 
Why are players out after the server? Please fix if you can
thx man

Morell 07-22-2014 16:24

Re: CS:GO Z:R fixes and workarounds
 
Quote:

Originally Posted by bebe9b (Post 2172035)
Why are players out after the server? Please fix if you can
thx man

Sorry, I don't know what you mean. Could you be more clear?

bebe9b 07-22-2014 16:38

Re: CS:GO Z:R fixes and workarounds
 
Some players are disconnected from the zombie server and I don`t know why
The game crashes because of the server

Jargon 07-22-2014 17:04

Re: CS:GO Z:R fixes and workarounds
 
Hey Morell, does this include all of the previous changes as well or just knockback?

If it includes all, do you mind if I merge the knockback.inc with my sticky post (crediting you of course) to keep things easy to find? I've been working on some other fixes for a few months now that I should be adding soon, so it'd be silly to have two posts to keep track of.


All times are GMT -4. The time now is 20:29.

Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.