Code: Show/Hide #include "../asss.h" struct adata { int on; }; struct pdata { time_t last; int count; }; /* global data */ local int adkey; local int pdkey; local Iplayerdata *pd; local Ilogman *lm; local Inet *net; local Imapdata *mapdata; local Iarenaman *aman; local Igame *game; local void DoChecksum(struct S2CWeapons *pkt) { int i; u8 ck = 0; pkt->checksum = 0; for (i = 0; i < sizeof(struct S2CWeapons) - sizeof(struct ExtraPosData); i++) ck ^= ((unsigned char*)pkt)[i]; pkt->checksum = ck; } local void Pppk(Player *p, byte *p2, int len) { struct C2SPosition *pos = (struct C2SPosition *)p2; Arena *arena = p->arena; struct adata *ad = P_ARENA_DATA(arena, adkey); if (len < 22) return; /* handle common errors */ if (!arena || !ad->on) return; if (p->p_ship == SHIP_SPEC) return; if (pos->status & STATUS_ANTIWARP && mapdata->InRegion(arena, "noanti", pos->x>>4, pos->y>>4)) { struct pdata *data = PPDATA(p, pdkey); //lm->LogP(L_DRIVEL, "hs_antiwarp", p, "removing anti."); if (data->last + 50 < current_ticks()) { if (data->count < 4) { data->count++; struct S2CWeapons wpn = { S2C_WEAPON, pos->rotation, pos->time & 0xFFFF, pos->x, pos->yspeed, p->pid, pos->xspeed, 0, pos->status & ~STATUS_ANTIWARP, 0, pos->y, pos->bounty }; DoChecksum(&wpn); net->SendToArena(arena, NULL, (byte*)&wpn, sizeof(struct S2CWeapons) - sizeof(struct ExtraPosData), NET_PRI_P4); } else { Target t; t.type = T_PLAYER; t.u.p = p; game->GivePrize(&t, -20, 1); data->count = 0; } //update last time data->last = current_ticks(); } } } EXPORT int MM_hs_antiwarp(int action, Imodman *mm, Arena *arena) { if (action == MM_LOAD) { pd = mm->GetInterface(I_PLAYERDATA, ALLARENAS); lm = mm->GetInterface(I_LOGMAN, ALLARENAS); net = mm->GetInterface(I_NET, ALLARENAS); mapdata = mm->GetInterface(I_MAPDATA, ALLARENAS); aman = mm->GetInterface(I_ARENAMAN, ALLARENAS); game = mm->GetInterface(I_GAME, ALLARENAS); if (!pd || !lm || !net || !mapdata || !aman || !game) return MM_FAIL; adkey = aman->AllocateArenaData(sizeof(struct adata)); if (adkey == -1) return MM_FAIL; pdkey = pd->AllocatePlayerData(sizeof(struct pdata)); if (pdkey == -1) return MM_FAIL; net->AddPacket(C2S_POSITION, Pppk); return MM_OK; } else if (action == MM_UNLOAD) { net->RemovePacket(C2S_POSITION, Pppk); aman->FreeArenaData(adkey); pd->FreePlayerData(pdkey); mm->ReleaseInterface(pd); mm->ReleaseInterface(lm); mm->ReleaseInterface(net); mm->ReleaseInterface(mapdata); mm->ReleaseInterface(aman); mm->ReleaseInterface(game); return MM_OK; } else if (action == MM_ATTACH) { struct adata *ad = P_ARENA_DATA(arena, adkey); ad->on = 1; return MM_OK; } else if (action == MM_DETACH) { struct adata *ad = P_ARENA_DATA(arena, adkey); ad->on = 0; return MM_OK; } return MM_FAIL; } |