Code: Show/Hide #include "asss.h"
/* Interfaces */ local Imodman *mm; local Ichat *chat; local Igame *game; local Iplayerdata *pd; local Icmdman *cmd; local Iconfig *cfg; local Iarenaman *aman; local Imainloop *ml; /* Player data */ typedef struct ZombieData { int died; } ZombieData; local int playerKey; /* Arena data */ typedef struct EventData { int isRunning; int humanSpawnX; int humanSpawnY; int zombieSpawnX; int zombieSpawnY; int humanShip; int zombieShip; } EventData; local int arenaKey; /* Function Prototypes */ local void Czombiestart(const char *command, const char *params, Player *p, const Target *target); local void Czombiestop(const char *command, const char *params, Player *p, const Target *target); local void Kill(Arena *arena, Player *killer, Player *killed, int bounty, int flags, int *pts, int *green); local void ShipChange(Player *p, int newship, int newfreq); local void start(Arena *arena); local void stop(Arena *arena); local int CountHumans(Arena *arena); /* Functions */ local void start(Arena *arena) { // Initializing all event data ZombieData *zData; EventData *eData = P_ARENA_DATA(arena, arenaKey); // Check to make sure game isn't running if(eData->isRunning == TRUE) { // chat->SendMessage(p, "Event is already running, Zombie event canceled."); return; } eData->isRunning = TRUE; // Arena data initialization eData->humanSpawnX = cfg->GetInt(arena->cfg, "Zombie", "HumanSpawn-X", 512); eData->humanSpawnY = cfg->GetInt(arena->cfg, "Zombie", "HumanSpawn-Y", 512); eData->zombieSpawnX = cfg->GetInt(arena->cfg, "Zombie", "ZombieSpawn-X", 512); eData->zombieSpawnY = cfg->GetInt(arena->cfg, "Zombie", "ZombieSpawn-Y", 512); eData->humanShip = cfg->GetInt(arena->cfg, "Zombie", "HumanShip", SHIP_WARBIRD) - 1; // Err, fix because players will want to write eData->zombieShip = cfg->GetInt(arena->cfg, "Zombie", "ZombieShip", SHIP_SPIDER) - 1; // HumanShip = 1 in conf, AS3 uses 0 for WB // Continue with Zombie initialization // This stuff is needed just to loop through players and warp correctly. Player *tempPlayer; Link *link; Target t; t.type = T_PLAYER; pd->Lock(); // Lock, necessary when cycling through players FOR_EACH_PLAYER_P(tempPlayer, zData, playerKey) // Cycles through each player, I use this to set playerdata and warp. { zData->died = FALSE; if (tempPlayer->p_freq == 0) // If human... { t.u.p = tempPlayer; game->WarpTo (&t, eData->humanSpawnX, eData->humanSpawnY); // Warp to human spawn. } else if (tempPlayer->p_freq == 1) // Repeat for Zombies. { t.u.p = tempPlayer; // I still don't understand t.u.p. game->WarpTo (&t, eData->zombieSpawnX, eData->zombieSpawnY); } } pd->Unlock(); // End cycle and lock chat->SendArenaSoundMessage(arena, SOUND_GOAL, "GOGOGO!"); mm->RegCallback(CB_KILL, Kill, arena); mm->RegCallback(CB_SHIPCHANGE, ShipChange, arena); } local void stop(Arena *arena) { EventData *eData = P_ARENA_DATA(arena, arenaKey); chat->SendArenaMessage(arena, "Game over. Searching for survivors...."); Player *temp; Link *link; pd->Lock(); FOR_EACH_PLAYER(temp) { if (temp->p_ship == eData->humanShip) chat->SendArenaMessage(temp->arena, "%s has survived!", temp->name); } pd->Unlock(); eData->isRunning = FALSE; mm->UnregCallback(CB_SHIPCHANGE, ShipChange, arena); mm->UnregCallback(CB_KILL, Kill, arena); } local int CountHumans(Arena *arena) { int players = 0; EventData *eData = P_ARENA_DATA(arena, arenaKey); Player *temp; Link *link; pd->Lock(); FOR_EACH_PLAYER(temp) { if (temp->p_ship == eData->humanShip) players++; } pd->Unlock(); return players; } /* Commands */ /* ?zombiestart: starts the Zombie event */ local void Czombiestart(const char *command, const char *params, Player *p, const Target *target) { start(p->arena); } local helptext_t zombiestart_help = "Module: zombie:zombie\n" "Possible Targets: none\n" "Arguments: none\n" "Starts the Zombie event."; /* ?zombiestop: stops the Zombie event */ local void Czombiestop(const char *command, const char *params, Player *p, const Target *target) { stop(p->arena); } local helptext_t zombiestop_help = "Module: zombie:zombie\n" "Possible Targets: none\n" "Arguments: none\n" "Stops the Zombie event."; /* Callbacks */ local void Kill(Arena *arena, Player *killer, Player *killed, int bounty, int flags, int *pts, int *green) { ZombieData *zData = PPDATA(killed, playerKey); EventData *eData = P_ARENA_DATA(arena, arenaKey); if (zData->died == TRUE) return; if(zData->died == FALSE) { zData->died = TRUE; game->SetFreqAndShip(killed, eData->zombieShip, 1); chat->SendArenaSoundMessage(killed->arena, SOUND_SCREAM, "%s dies a miserable, horrible death at the hands of a Zombie!", killed->name); } if (CountHumans(arena) <= 1) stop(arena); } local void ShipChange(Player *p, int newship, int newfreq) { ZombieData *zData = PPDATA(p, playerKey); EventData *eData = P_ARENA_DATA(p->arena, arenaKey); if (newship == eData->humanShip) { zData->died = FALSE; game->SetFreq(p, 0); } else if (newship == eData->zombieShip) { zData->died = TRUE; game->SetFreq(p, 1); } } /* Loading and unloading */ EXPORT int MM_zombie(int action, Imodman *mm_, Arena *arena) { if (action == MM_LOAD) { mm = mm_; chat = mm->GetInterface(I_CHAT, ALLARENAS); game = mm->GetInterface(I_GAME, ALLARENAS); pd = mm->GetInterface(I_PLAYERDATA, ALLARENAS); cmd = mm->GetInterface(I_CMDMAN, ALLARENAS); cfg = mm->GetInterface(I_CONFIG, ALLARENAS); aman = mm->GetInterface(I_ARENAMAN, ALLARENAS); ml = mm->GetInterface(I_MAINLOOP, ALLARENAS); if (!chat || !game || !pd || !cmd || !cfg || !aman || !ml) return MM_FAIL; return MM_OK; } else if (action == MM_UNLOAD) { mm->ReleaseInterface(ml); mm->ReleaseInterface(aman); mm->ReleaseInterface(cfg); mm->ReleaseInterface(cmd); mm->ReleaseInterface(pd); mm->ReleaseInterface(game); mm->ReleaseInterface(chat); return MM_OK; } else if (action == MM_ATTACH) { playerKey = pd->AllocatePlayerData(sizeof(ZombieData)); if (playerKey == -1) return MM_FAIL; arenaKey = aman->AllocateArenaData(sizeof(EventData)); if (arenaKey == -1) return MM_FAIL; cmd->AddCommand("zombiestart", Czombiestart, arena, zombiestart_help); cmd->AddCommand("zombiestop", Czombiestop, arena, zombiestop_help); return MM_OK; } else if (action == MM_DETACH) { cmd->RemoveCommand("zombiestop", Czombiestop, arena); cmd->RemoveCommand("zombiestart", Czombiestart, arena); aman->FreeArenaData(arenaKey); pd->FreePlayerData(playerKey); return MM_OK; } return MM_FAIL; } |
Smong wrote: |
Unless you lock the arena players can just change back to a human ship and the module will set them back as a human.
Also might want to add the PlayerAction callback to check if you should stop the game when players leave. If you don't know python you should look into it, something like zombies will be very easy to make in python. But I already made zombies in py, it's in my port of the merv elim bot (the game is called "spiders"). |