Raised This Month: $51 Target: $400
 12% 

[REQ][L4D2] Loot of Zombies plugin improvements


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Mika Misori
Senior Member
Join Date: Sep 2022
Old 11-04-2022 , 18:05   [REQ][L4D2] Loot of Zombies plugin improvements
Reply With Quote #1

Hi. I would like to request several improvements to Loot of Zombies plugin (attached last working .sp version from original thread).

1. Add drop from witches.
Currently you can configure drop from any special infected, except witch.

I tried to add it by myself, copying by analogy existing cvars and variables and renaming them in the witch, lol. But, no luck. As far as I understand, this is because the witch is an unplayable character, so you can't get her in the code as well as other special infected like this:
Code:
int Target = GetClientOfUserId(GetEventInt(hEvent, "userid"));

if (GetClientTeam(Target) != 3)
		return Plugin_Continue;
	
// Smoker = 1
// Boomer = 2
// Hunter = 3
// Spitter = 4
// Jockey = 5
// Charger = 6
// Tank = 8
// Witch = 7 I tried adding it this way, but it didn't work.

if (GetClientZC(Target) == 3)
	{
		for (int i = 0; i < GetConVarInt(l4d2_loot_h_drop_items) + GetConVarInt(l4d2_loot_g_bonus); i++)
			LootDropItem(Target, GetRandomItem(GetRandomGroup("Hunter")));
	}
	if (GetClientZC(Target) == 2)
              ...etc
I'm not a developer, so very crookedly tried to copy and paste code with the witch from other plugins, I managed to get a drop from her, but it works very unstable, every once in a while. And items drop out not from the witch, but around her. Here is my copy-pasted piece of code:

Code:
char class[STRINGLENGTH_CLASSES];
int maxents = GetMaxEntities();
for (int i = MaxClients+1; i <= maxents; i++)
	{
		if (!IsValidEdict(i)) continue;
		GetEdictClassname(i, class, sizeof(class));
			
		if (strcmp(class, CLASS_WITCH) != 0) continue;
						
			for (int j = 0; j < GetConVarInt(l4d2_loot_b_drop_items) + GetConVarInt(l4d2_loot_g_bonus); j++)
				Target = 2;
				PrintToChatAll("LootDropItem Boomer");
				LootDropItem(Target, GetRandomItem(GetRandomGroup("Boomer")));
	}
Drop by killing witch, but item from boomer group of items drop, because otherwise it does not work. And I have no idea what's going on here.

1.1. Extra wish — drop from un/commons.
If possible to add a witch, then is it possible to add by analogy drop from common infected and uncommon infected?

2. Add to the drop list laser sights.
To be able to configure cvar drop chance by analogy with other items. To spawn lasers spread out on the floor, after killing a special infected.

--
I would be grateful for any help.

And I can pay for these improvements, for each separately or at once for all together. PM me how much it will cost (I can pay only in crypto).
Attached Files
File Type: sp Get Plugin or Get Source (l4d2_loot.sp - 71 views - 72.8 KB)
Mika Misori is offline
Spirit_12
Veteran Member
Join Date: Dec 2012
Location: Toronto, CA
Old 11-04-2022 , 20:22   Re: [REQ][L4D2] Loot of Zombies plugin improvements
Reply With Quote #2

While I don't have any interest in this plugin, I do feel the need to explain why your code doesn't work.

To begin your logic is correct. Your first code snippet will not work as Witch is not a playable character, therefore the event and its subsequent function Event_PlayerDeath will not work. A little background on the game events.

PHP Code:
// We hook the event here. Done in OnPluginStart function.
HookEvent("player_death"Event_PlayerDeath);

//This is the function that gets called after the hook.
public Action Event_PlayerDeath(Event hEvent, const char[] strNamebool DontBroadcast)
{

You can read about all the events on this page.

https://wiki.alliedmods.net/Left_4_Dead_2_Events

Now the good thing is that if you look at the events page you can find an event dedicated to witch's death named witch_killed.

Applying the same logic from above, you can hook it and create a new function.

PHP Code:
// We hook the event here.
HookEvent("witch_killed"Event_WitchKilled);

//This is the function that gets called after the hook.
public Action Event_WitchKilled(Event hEvent, const char[] strNamebool DontBroadcast)
{
     
// This code will run every time a witch is killed. 

The way the plugin is coded is that everytime Event_PlayerDeath is called it checks who died, were they a zombie and what class they were. Once that is done, it calls this code below.

PHP Code:
// This is if the zombie class was Tank
for (int i 0GetConVarInt(l4d2_loot_t_drop_items) + GetConVarInt(l4d2_loot_g_bonus); i++)
            
LootDropItem(TargetGetRandomItem(GetRandomGroup("Tank"))); 
There are three functions above.
  • LootDropItem
  • GetRandomItem
  • GetRandomGroup

First two you can use as is as they are not dependent on the zombie class. However last one accepts zombie name as a string. Notice "Tank" ?? I would say for starting just use the string for "Tank" or another SI that already exists in the code as you are still learning.

To combine everything from above, you want to run the code when witch is killed.

PHP Code:
// We hook the event here.
HookEvent("witch_killed"Event_WitchKilled);

//This is the function that gets called after the hook.
public Action Event_WitchKilled(Event hEvent, const char[] strNamebool DontBroadcast)
{
     
// Now we can check for whether the a few things listed on the events page as to who killed the witch, what was the entity ID of the witch, was it one shot kill, was it a melee and if it was bride variant. But for now lets ignore those things and keep it simple. 
     // This is if the zombie class was Tank
     
for (int i 0GetConVarInt(l4d2_loot_t_drop_items) + GetConVarInt(l4d2_loot_g_bonus); i++)
            
LootDropItem(TargetGetRandomItem(GetRandomGroup("Tank"))); 

The above code would lead to sharing the same cvars for witch drop as they are set for Tank.

Its a learning process and I did not test the above code at all, but just went with the snippets from the existing code. Hopefully it would get you started somewhere. Feel free to ask questions.
__________________
Spirit_12 is offline
Mika Misori
Senior Member
Join Date: Sep 2022
Old 11-13-2022 , 07:43   Re: [REQ][L4D2] Loot of Zombies plugin improvements
Reply With Quote #3

Quote:
Originally Posted by Spirit_12 View Post
While I don't have any interest in this plugin, I do feel the need to explain why your code doesn't work.
Thank you so much for your help. It became a little clearer what's going on in the code : )

I tried to put a hook on the start of the plugin and created a separate function:
Code:
public void OnPluginStart()
{
    ...
    // We hook the event here.
    HookEvent("witch_killed", Event_WitchKilled);
    ...
}

...

// This is the function that gets called after the hook.
public Action Event_WitchKilled(Event hEvent, const char[] strName, bool DontBroadcast)
{
    int Target = 8;
    for (int j = 0; j < GetConVarInt(l4d2_loot_t_drop_items) + GetConVarInt(l4d2_loot_g_bonus); j++)
        LootDropItem(Target, GetRandomItem(GetRandomGroup("Tank")));
}
Also put PrintToChatAll messages everywhere in this code to track which functions are triggered.

Tested it:
When you kill a witch function Event_WitchKilled is called, gets into the loop forj, but the items in the game still does not drop, no matter how many I tried and did not try to call different drop functions in this place.

I don't know what I'm doing wrong.
Mika Misori is offline
alasfourom
Senior Member
Join Date: Feb 2022
Location: Saudi Arabia
Old 11-13-2022 , 13:26   Re: [REQ][L4D2] Loot of Zombies plugin improvements
Reply With Quote #4

Use this plugin by: Earendil > [L4D & L4D2] Loot Boxes

The script bellow I made from the link above > Killing a witch will give you a random gift

PHP Code:
#include <sdktools>
#include <sdkhooks>
#include <sourcemod>

#pragma semicolon 1
#pragma newdecls required

public void OnPluginStart() 
{
    
HookEvent("player_death"Event_PlayerDeath);
}

void Event_PlayerDeath(Event event, const char[] namebool dontBroadcast)
{
    
int client GetClientOfUserId(event.GetInt("userid"));
    if (
client) return;
    
    
char sName[16];
    
float vPos[3];
    
int entity event.GetInt("entityid");
    
GetEntityNetClass(entitysNamesizeof(sName));
    if(
StrEqual(sName"witch"false))
    {
        
GetEntPropVector(entityProp_Send"m_vecOrigin"vPos);
        
DropRandomGift(entityvPos);
    }
    return;
}

void DropRandomGift(int entityfloat vPos[3])
{
    
entity CreateEntityByName("prop_physics_override");
    if (!
IsValidEntity(entity)) return;
    
    
GetRandomGiftToDrop(entity);
    
DispatchKeyValue(entity"spawnflags""8448");
    
DispatchKeyValue(entity"glowstate""3");
    
DispatchKeyValue(entity"glowcolor""0 255 255");
    
DispatchKeyValue(entity"glowrange""500");
        
    
DispatchSpawn(entity);
    
TeleportEntity(entityvPosNULL_VECTORNULL_VECTOR);
}

void GetRandomGiftToDrop(int entity)
{
    switch (
GetRandomInt(1,12))
    {
        case 
1DispatchKeyValue(entity"model""models/w_models/weapons/w_eq_Medkit.mdl");
        case 
2DispatchKeyValue(entity"model""models/w_models/weapons/w_eq_defibrillator.mdl");
        case 
3DispatchKeyValue(entity"model""models/w_models/weapons/w_grenade_launcher.mdl");
        case 
4DispatchKeyValue(entity"model""models/w_models/weapons/w_eq_painpills.mdl");
        case 
5DispatchKeyValue(entity"model""models/w_models/weapons/w_eq_adrenaline.mdl");
        case 
6DispatchKeyValue(entity"model""models/w_models/weapons/w_shotgun_spas.mdl");
        case 
7DispatchKeyValue(entity"model""models/w_models/weapons/w_rifle_m16a2.mdl");
        case 
8DispatchKeyValue(entity"model""models/w_models/weapons/w_m60.mdl");
        case 
9DispatchKeyValue(entity"model""models/w_models/weapons/w_rifle_ak47.mdl");
        case 
10DispatchKeyValue(entity"model""models/w_models/weapons/w_sniper_mini14.mdl");
        case 
11DispatchKeyValue(entity"model""models/w_models/weapons/w_eq_pipebomb.mdl");
        case 
12DispatchKeyValue(entity"model""models/w_models/weapons/w_eq_molotov.mdl");
    }

__________________

Last edited by alasfourom; 11-13-2022 at 14:20. Reason: I added a switch with GetRandomInt to give random items
alasfourom is offline
Spirit_12
Veteran Member
Join Date: Dec 2012
Location: Toronto, CA
Old 11-13-2022 , 14:14   Re: [REQ][L4D2] Loot of Zombies plugin improvements
Reply With Quote #5

Quote:
Originally Posted by Mika Misori View Post
Thank you so much for your help. It became a little clearer what's going on in the code : )

I tried to put a hook on the start of the plugin and created a separate function:
Code:
public void OnPluginStart()
{
    ...
    // We hook the event here.
    HookEvent("witch_killed", Event_WitchKilled);
    ...
}

...

// This is the function that gets called after the hook.
public Action Event_WitchKilled(Event hEvent, const char[] strName, bool DontBroadcast)
{
    int Target = 8;
    for (int j = 0; j < GetConVarInt(l4d2_loot_t_drop_items) + GetConVarInt(l4d2_loot_g_bonus); j++)
        LootDropItem(Target, GetRandomItem(GetRandomGroup("Tank")));
}
Also put PrintToChatAll messages everywhere in this code to track which functions are triggered.

Tested it:
When you kill a witch function Event_WitchKilled is called, gets into the loop forj, but the items in the game still does not drop, no matter how many I tried and did not try to call different drop functions in this place.

I don't know what I'm doing wrong.
In my opinion, the problem with your code is that you are using:

PHP Code:
int Target 8
8 is the zombie class tank and in the original code it is used to check whether the target is a tank or not. In your code you are using it as a player index, so when the plugin tries to spawn an item, it looks for player with index 8. I'm assuming you don't have 8 players in the server while you were testing so it doesn't work.

In this case we want to get the ID of the witch. You can do that from the event code.

PHP Code:
// This is the function that gets called after the hook.
public Action Event_WitchKilled(Event hEvent, const char[] strNamebool DontBroadcast)
{
    
int Target hEvent.GetInt("witchid");;
    for (
int j 0GetConVarInt(l4d2_loot_t_drop_items) + GetConVarInt(l4d2_loot_g_bonus); j++)
        
LootDropItem(TargetGetRandomItem(GetRandomGroup("Tank")));

Despite the above, I'm still not convinced that the item would spawn because the code used to spawn items is this.

PHP Code:
FakeClientCommand 
and as we have established a witch is not a client, but an entity. Think of client as any playable character.

To check the above code you can change line 10 from:

PHP Code:
#define PRINT_DROP false 
to
PHP Code:
#define PRINT_DROP true 
This should trigger the following message in the console.

PHP Code:
PrintToServer("[L4D2LOOT] LOOT :: %s"ItemName); 
This way you would know that the item was about to be spawned or not.


A different approach would be to get the player index who killed the witch from the event rather than getting the witch index.

PHP Code:
int Target hEvent.GetInt("userid"); 
This way the player who killed the witch would automatically get the item rather than him having to pick it up from where the witch was killed. A little compromise but may be its worth the shot.
__________________
Spirit_12 is offline
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 02:47.


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