Here is the actual function from mob.cpp:
Code:
void Mob::DoKnockback(Mob *caster, uint32 pushback, uint32 pushup)
{
if(IsClient())
{
CastToClient()->SetKnockBackExemption(true);
EQApplicationPacket* outapp_push = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
PlayerPositionUpdateServer_Struct* spu = (PlayerPositionUpdateServer_Struct*)outapp_push->pBuffer;
double look_heading = caster->CalculateHeadingToTarget(GetX(), GetY());
look_heading /= 256;
look_heading *= 360;
if(look_heading > 360)
look_heading -= 360;
//x and y are crossed mkay
double new_x = pushback * sin(double(look_heading * 3.141592 / 180.0));
double new_y = pushback * cos(double(look_heading * 3.141592 / 180.0));
spu->spawn_id = GetID();
spu->x_pos = FloatToEQ19(GetX());
spu->y_pos = FloatToEQ19(GetY());
spu->z_pos = FloatToEQ19(GetZ());
spu->delta_x = NewFloatToEQ13(new_x);
spu->delta_y = NewFloatToEQ13(new_y);
spu->delta_z = NewFloatToEQ13(pushup);
spu->heading = FloatToEQ19(GetHeading());
spu->padding0002 =0;
spu->padding0006 =7;
spu->padding0014 =0x7f;
spu->padding0018 =0x5df27;
spu->animation = 0;
spu->delta_heading = NewFloatToEQ13(0);
outapp_push->priority = 6;
entity_list.QueueClients(this, outapp_push, true);
CastToClient()->FastQueuePacket(&outapp_push);
}
}
As you can see, "THIS" needs to be a client or it won't do anything. A bit odd since it was added as a mob perl object. Anyway, I think the use would be like this:
$client->DoKnockback($npc, x, x);
I don't know what the pushback and pushup should be set to, so I just used "x" in the example, but I imagine you can figure that part out with some simple testing once you have it basically working.
I would suggest testing it with EVENT_SAY first to make sure you are using it properly. If you want to use it in EVENT_TIMER, then you are going to have a bit of an issue. The $npc variable is exported to EVENT_TIMER for npc scripts, but since it is a timer, there is no actual client triggering it, so there is no $client variable exported to EVENT_TIMER. If you want to use a client as a pointer like that from EVENT_TIMER, my best suggestion would be to save the entity ID of the client you want to knockback from one of the other sub events such as EVENT_COMBAT or whatever. Then, in the EVENT_TIMER, you can get the client by the entity ID and validate that you were able to get the client before trying to use it as a pointer. Otherwise, if you try to just save the client as a variable outside the sub and the client zoned or died or whatever, it can cause a zone crash if you don't validate it still exists first.
Alternatively, you can just get the NPCs current target and check if it is a client, then knock it back. Or, you can do an entity list search through the client list and use knockback on any or all of the clients in the zone or within X distance from the NPC.
The possibilities are endless.