Raised This Month: $ Target: $400
 0% 

(Solved) [L4D] Where is logical mistake?


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
olj
Veteran Member
Join Date: Jun 2009
Old 09-30-2009 , 07:54   (Solved) [L4D] Where is logical mistake?
Reply With Quote #1

Ok, this code deletes medkits on every round start around first found survivor in 800 radius. However one of my comrades reported about this plugin removing medkits near FINALE RADIOS! Can someone check it for logical mistakes maybe im doing something wrong...?

I think this can be somehow related to events firing sequence in finales or something like that. Any help appreciated.

PHP Code:

new Float:vOrigin[MAXPLAYERS+1][3];
new 
bool:Found false;
new 
Handle:MedkitsTimer[1];
new 
Handle:hMedkitsTime;

public 
OnPluginStart()
    {
        
HookEvent("round_start"EventMEDSEventHookMode_Post);
        
HookEvent("round_end"EventRoundEndEventHookMode_Pre);
        
hMedkitsTime CreateConVar("l4d_medkits_time""24.0""Time before we give medkits"CVAR_FLAGS);
    }
    
public 
Action:EventMEDS(Handle:event, const String:name[], bool:dontBroadcast)
    {
        
MedkitsTimer[0] = CreateTimer(1.0TimerDelay_TIMER_FLAG_NO_MAPCHANGE|TIMER_REPEAT);
        new 
Flags GetCommandFlags("give");
        
CreateTimer(GetConVarFloat(hMedkitsTime), GiveMedkitsTimerany:FlagsTIMER_FLAG_NO_MAPCHANGE);
    }

public 
Action:EventRoundEnd(Handle:event, const String:name[], bool:dontBroadcast)
    {
        
Found false;
    }
    
public 
Action:TimerDelay(Handle:timer)
    {
        if (
Found)
            {
                
MedkitsTimer[0] = INVALID_HANDLE;
                return 
Plugin_Stop;
            }
        
        new 
Float:FirstSurvivorOrigin[3];
                for (new 
i=1;i<MaxClients;i++)
                    {
                        if (
IsValidClient(i))
                            {
                                
// decl String:Name[MAX_NAME_LENGTH];
                                // GetClientName(i, Name, MAX_NAME_LENGTH);
                                
GetClientAbsOrigin(i,vOrigin[i]);
                                
FirstSurvivorOrigin vOrigin[i];
                                
Found true;
                                break;
                            }
                    }

        new 
ent = -1;
        while ((
ent FindEntityByClassname2(ent"weapon_first_aid_kit_spawn")) != -1)
            {
                        new 
Float:MEDlocation[3];
                        
GetEntPropVector(entProp_Send"m_vecOrigin"MEDlocation);
                        new 
Distance RoundToNearest(GetVectorDistance(FirstSurvivorOriginMEDlocationfalse));
                        if (
Distance<800)
                            {
                                
RemoveEdict(ent);
                            }
            }
        return 
Plugin_Continue;
    }

public 
Action:GiveMedkitsTimer(Handle:timerany:Flags)
    {
        for (new 
1<=MaxClientsi++)
            {
                if ((
IsClientInGame(i))&&(IsPlayerAlive(i))&&(GetClientTeam(i)==2)&&(i>0)) ExecuteCommand(i"give""first_aid_kit");
                if (
i==MaxClients)
                    {
                        
SetCommandFlags("give"Flags);
                    }
            }
    }    
    
stock FindEntityByClassname2(startEnt, const String:classname[])
{
/* If startEnt isn't valid shifting it back to the nearest valid one */
while (startEnt > -&& !IsValidEntity(startEnt)) startEnt--;
return 
FindEntityByClassname(startEntclassname);
}
    
ExecuteCommand(ClientString:strCommand[], String:strParam1[])
{
    if (
Client==0) return;
    new 
Flags GetCommandFlags(strCommand);
    
SetCommandFlags(strCommandFlags & ~FCVAR_CHEAT);
    
FakeClientCommand(Client"%s %s"strCommandstrParam1);
}
        
public 
IsValidClient(client)
{
    if (
client == 0)
        return 
false;
    
    if (!
IsClientConnected(client))
        return 
false;
    
    
//if (IsFakeClient(client))
        //return false;
    
    
if (!IsClientInGame(client))
        return 
false;
    
    if (!
IsPlayerAlive(client))
        return 
false;
        
    if (
GetClientTeam(client)!=2)
        return 
false;
    return 
true;

__________________

Last edited by olj; 10-03-2009 at 02:54.
olj is offline
Frus
Senior Member
Join Date: Aug 2009
Old 09-30-2009 , 16:34   Re: [L4D] Where is logical mistake?
Reply With Quote #2

I am using the distance from "prop_door_rotating_checkpoint" (i.e. safe room door) to determine safe room medkits in finales for one of my plugins.

Anyways, could I inquire why you made a plugin to remove kits on the ground and give them directly to the survivors?
Frus is offline
Flynn
Senior Member
Join Date: Sep 2009
Old 10-01-2009 , 03:01   Re: [L4D] Where is logical mistake?
Reply With Quote #3

Quote:
Originally Posted by olj View Post
Ok, this code deletes medkits on every round start around first found survivor in 800 radius.
You could run at the very least a standard debugging approach by printing out the two vectors and the given distance to figure out why.

Your uh, entity code is what I'd call 'highly bastardised' (incredibly confusing - the more so, the more likely there are to be bugs in it).

Just to pick out some peices...
Code:
new ent = -1;
    while ((ent = FindEntityByClassname2(ent, "weapon_first_aid_kit_spawn")) != -1)
Code:
stock FindEntityByClassname2(startEnt, const String:classname[])
{
/* If startEnt isn't valid shifting it back to the nearest valid one */
while (startEnt > -1 && !IsValidEntity(startEnt)) startEnt--;
return FindEntityByClassname(startEnt, classname);
}
Bastardised parts highlighted. You're starting from -1, with a loop that breaks out on -1 (with a deincrementation operation), and returns ??? because FindEntity is given -1;

A better question is why is your code even able to remove medkits?

Edit: I presume FindEntity starts from -1, counts up, returns the first entity, the loop deincrements it back down, and because FindEntity only returns -1 when it -cannot find any more medkits- it gets trapped in an infinite loop until every single one is removed (which, when the player arrives at the finale spot, gets removed because the operation is still continuously operating - because there are still kits out there).

In short; Assumption and Presumption fail.

Quote:
Originally Posted by SourceMod Documentation
Return:
Entity index >= 0 if found, -1 otherwise.

Last edited by Flynn; 10-01-2009 at 03:10.
Flynn is offline
Send a message via MSN to Flynn Send a message via Skype™ to Flynn
Flynn
Senior Member
Join Date: Sep 2009
Old 10-01-2009 , 03:14   Re: [L4D] Where is logical mistake?
Reply With Quote #4

As for the solution, you should not try to use hacky hacky cody buggy idea, but instead find the maximum number of entities and do a single pass (incrementing upwards) until your entity number is either equal to or exceeds the maximum.

Heading in the other direction won't work. Not with FindEntityByClassname anyway.

Remember Kids; lazy coding costs time!

Edit: Also, I don't recommend Copy Pasta.

Quote:
exvelSeptember 2, 2009, 5:55 amI've just replaced this function with my own that automatically checks if start entity is valid and if not just shifts to the nearest valid one:
1: stock FindEntityByClassname2(startEnt, const String:classname[])
2: {
3:
/* If startEnt isn't valid shifting it back to the nearest valid one */
4:
while (startEnt > -1 && !IsValidEntity(startEnt)) startEnt--;
5:

6:
return FindEntityByClassname(startEnt, classname);
7: }




Last edited by Flynn; 10-01-2009 at 03:20.
Flynn is offline
Send a message via MSN to Flynn Send a message via Skype™ to Flynn
MockingBird
Member
Join Date: Mar 2005
Old 10-01-2009 , 04:44   Re: [L4D] Where is logical mistake?
Reply With Quote #5

Quote:
Originally Posted by Flynn View Post
You could run at the very least a standard debugging approach by printing out the two vectors and the given distance to figure out why.

Your uh, entity code is what I'd call 'highly bastardised' (incredibly confusing - the more so, the more likely there are to be bugs in it).

Just to pick out some peices...
Code:
new ent = -1;
    while ((ent = FindEntityByClassname2(ent, "weapon_first_aid_kit_spawn")) != -1)
Code:
stock FindEntityByClassname2(startEnt, const String:classname[])
{
/* If startEnt isn't valid shifting it back to the nearest valid one */
while (startEnt > -1 && !IsValidEntity(startEnt)) startEnt--;
return FindEntityByClassname(startEnt, classname);
}
Bastardised parts highlighted. You're starting from -1, with a loop that breaks out on -1 (with a deincrementation operation), and returns ??? because FindEntity is given -1;

A better question is why is your code even able to remove medkits?

Edit: I presume FindEntity starts from -1, counts up, returns the first entity, the loop deincrements it back down, and because FindEntity only returns -1 when it -cannot find any more medkits- it gets trapped in an infinite loop until every single one is removed (which, when the player arrives at the finale spot, gets removed because the operation is still continuously operating - because there are still kits out there).

In short; Assumption and Presumption fail.
That code is fine. 'ent' is initted to -1 because the FindEntityByClassname looks for entities PAST the index given. If you want to start at 0, the index needs to be -1. The new entity found is then past into the 'ent' variable making it no longer equal to -1, and hence making the boolean expression true. Then after the loop, that new ent is then passed into the FindEntity function, and it starts again. The FindEntity function will return -1 when no entity is found, exitting the loop.

If no entity is found, the ent value will then be equal to -1, which is why his next code checks for the ent value to be greater than -1 so that it wont operate on a none existant entity.

I use this loop allot, and it works fine for me. I dont play L4D, so I cant help you with your actual problem xD
MockingBird is offline
olj
Veteran Member
Join Date: Jun 2009
Old 10-01-2009 , 06:29   Re: [L4D] Where is logical mistake?
Reply With Quote #6

Quote:
Originally Posted by Frus View Post
I am using the distance from "prop_door_rotating_checkpoint" (i.e. safe room door) to determine safe room medkits in finales for one of my plugins.

Anyways, could I inquire why you made a plugin to remove kits on the ground and give them directly to the survivors?
Just a request from l4d-support.ru
__________________
olj is offline
olj
Veteran Member
Join Date: Jun 2009
Old 10-01-2009 , 06:44   Re: [L4D] Where is logical mistake?
Reply With Quote #7

To Flynn - the code works fine,except for finals, and that happens not all times, judging from what i've been told by reqester. And I actually trust Exvel in whats he doing with this stock function. And i dont want to loop through incredible amount of entities on the map, especially if i want only 4 of them. Copy pasting is fine, you dont want to invent a wheel, because its already invented. You haven't provided any help, except for some mysterious "DONT USE HACKY FUNCTIONS", lol, i know what I'm doing usually. And If I dont, I browse scripting forums and development section to find answers and adjust code untill it works.
__________________
olj is offline
Dragonshadow
BANNED
Join Date: Jun 2008
Old 10-01-2009 , 08:31   Re: [L4D] Where is logical mistake?
Reply With Quote #8

Whereas I have no clue what I'm doing half the time and thus have to ask everyone for help!

/humor
Dragonshadow is offline
AtomicStryker
Veteran Member
Join Date: Apr 2009
Location: Teutonia!!
Old 10-01-2009 , 08:50   Re: [L4D] Where is logical mistake?
Reply With Quote #9

Your mistake is fairly obvious to me. All you do is check for medkits around an 800 radius of the survivor (which is a lot). This would naturally delete the medkits on No Mercy Finale, being just above the starting safe room.


As an alternative you should just delete the 4 meds closest to the Survivors ^^
AtomicStryker is offline
Flynn
Senior Member
Join Date: Sep 2009
Old 10-01-2009 , 13:22   Re: [L4D] Where is logical mistake?
Reply With Quote #10

Quote:
Originally Posted by olj View Post
And I actually trust Exvel in whats he doing with this stock function. And i dont want to loop through incredible amount of entities on the map, especially if i want only 4 of them. Copy pasting is fine, you dont want to invent a wheel, because its already invented. You haven't provided any help, except for some mysterious "DONT USE HACKY FUNCTIONS", lol, i know what I'm doing usually. And If I dont, I browse scripting forums and development section to find answers and adjust code untill it works.
I never said anything was wrong with his functions. Although you are using his function for a purpose not intended - it's designed to find the first instance of a given entity starting from -1 for a single usage, not for a while loop that only breaks out when -1 is returned.

In short, his function works by rewinding back to -1 when it receives a higher than -1 number and whilst those numbers are valid entities, and FindEntityByClassname returns the entity index of the given class (or -1 if it doesn't find any). The point is, your loop only breaks out when it cannot find any more medkits, except, because the stock function 'rewinds' back to the start, it will always find medkits.

For example, if I have only three entities, 0 is the spawn point, 1 is a medkit that is nearby, and 2 is a medkit is far away, and it keeps restarting from 0 and removes 1 (but is still searching for valid medkits) and 2 is a valid medkit - it's going to keep returning 2 until 2 is removed, if you catch my drift.

I would take the liberty of testing that specific code, but I'm going to have to be content with people believing the mathematical distance to be at fault and wondering why the problem still exists even after reducing it (FYI 800 is a relatively 'small' distance, in ZPS 500 would heal zombies within a '4 man' radius).

I would have suspected distance but a lot of the finales in the standard campaigns are a good distance away.
Flynn is offline
Send a message via MSN to Flynn Send a message via Skype™ to Flynn
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


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


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