Name | Author | Game Mode | Rating | |||||
---|---|---|---|---|---|---|---|---|
Condemned | Violet CLM | Mutator | 9 |
#pragma description "Variant on LRS. One or more players are placed randomly on the red team, meaning they are Condemned, and timers count down next to their names. If a player's timer runs out, they are removed from the game. A condemned (red) player may roast a normal (blue) player to swap both their teams. Best played with a low max health, so people die a lot."
bool AtLeastOneRoast = false;
void onRoast(jjPLAYER@ victim, jjPLAYER@ killer) {
if (jjIsServer) {
AtLeastOneRoast = true;
if (victim.team == TEAM::BLUE && killer !is victim) {
jjChat("/swap " + (victim.playerID + 1) + " red");
jjChat("/swap " + (killer.playerID + 1) + " blue");
}
}
}
jjTEXTAPPEARANCE Monospaced(STRING::NORMAL);
void onLevelLoad() {
Monospaced.monospace = true;
Monospaced.spacing = 8;
}
array<int> Timers(32, 200);
bool onDrawGameModeHUD(jjPLAYER@, jjCANVAS@ canvas) {
const int x = 4;
int y = 11;
for (int i = 0; i < 32; ++i) {
const jjPLAYER@ other = jjPlayers[i];
if (other.isInGame) {
canvas.drawString(x, y, (other.teamRed ? "||" : "|||") + formatInt(i + 1, "0", 2) + " " + other.name.substr(0,3), STRING::SMALL, Monospaced);
canvas.drawRectangle(x + 58, y - 8, Timers[i] / 2, 10, !other.teamRed ? 34 : 25);
if (other.isLocal) //draw an orange > to mark localness, so you can find your timer easily
canvas.drawSprite(x - 8, y - 10, ANIM::FONT, 1, '>'[0] - 32, 1, SPRITE::SINGLEHUE, 40);
y += 16;
}
}
return true;
}
void onLevelBegin() {
if (jjIsServer) {
if (jjGameCustom != GAME::FR)
jjChat("/fr");
jjChat("/joinersspectate on");
jjChat("/spectating off");
if (!jjPlayers[0].isIdle) {
if (jjPlayers[0].isSpectating)
jjChat("/forcespectate 1 off");
if (jjPlayers[0].team != TEAM::BLUE)
jjChat("/swap 1 blue");
}
jjPrint("**** " + jjLevelName + " (" + jjLevelFileName + ") Condemned.mut");
} else {
jjSTREAM packet;
for (int i = 0; i < jjLocalPlayerCount; ++i)
packet.push(uint8(jjLocalPlayers[i].playerID));
jjSendPacket(packet);
}
}
void onReceive(jjSTREAM &in packet, int fromClientID) {
if (jjIsServer) {
if (!AtLeastOneRoast)
while (!packet.isEmpty()) {
uint8 playerID;
packet.pop(playerID);
const jjPLAYER@ player = jjPlayers[playerID];
if (player.clientID == fromClientID) {
if (player.isSpectating)
jjChat("/forcespectate " + (playerID + 1) + " off");
if (player.team != TEAM::BLUE)
jjChat("/swap " + (playerID + 1) + " blue");
} else
return;
}
} else {
while (!packet.isEmpty()) {
uint8 playerID;
packet.pop(playerID);
uint8 time;
packet.pop(time);
Timers[playerID] = time;
}
}
}
array<const jjPLAYER@> GetTeamPlayers(TEAM::Color team) {
array<const jjPLAYER@> result;
for (uint i = 0; i < 32; ++i) {
jjPLAYER@ possible = jjPlayers[i];
if (possible.isInGame && possible.team == team)
result.insertLast(possible);
}
return result;
}
void onMain() {
if (jjIsServer) {
if ((jjGameState == GAME::STARTED || jjGameState == GAME::OVERTIME) && jjGameTicks % 21 == 20) {
array<const jjPLAYER@>@ red = GetTeamPlayers(TEAM::RED);
for (uint i = 0; i < red.length; ++i) { //should be at most 1...
const jjPLAYER@ player = red[i];
if ((Timers[player.playerID] -= (jjGameState == GAME::STARTED ? 1 : 2)) <= 0) {
jjChat("/forcespectate " + (player.playerID + 1) + " on");
jjPrint("**** " + player.name + " eliminated.");
jjAlert(player.name + " is out!", true, STRING::MEDIUM);
}
}
jjSTREAM packet;
for (uint8 i = 0; i < 32; ++i) {
if (jjPlayers[i].isInGame) {
packet.push(i);
if (Timers[i] < 0)
packet.push(uint8(0));
else
packet.push(uint8(Timers[i]));
}
}
if (packet.getSize() <= 2) { //at most one player alive
if (packet.getSize() == 2) { //exactly one player alive
uint8 playerID;
packet.pop(playerID);
jjPrint("**** " + jjPlayers[playerID].name + " wins.");
jjAlert(jjPlayers[playerID].name + " wins!", true, STRING::MEDIUM);
}
jjChat("/stop");
for (uint i = 0; i < 32; ++i)
Timers[i] = 200;
AtLeastOneRoast = false;
return;
}
jjSendPacket(packet);
if (int(GetTeamPlayers(TEAM::RED).length) <= (int(GetTeamPlayers(TEAM::BLUE).length) - 1) / 4) {
int minimumRoasts = 9999;
array<const jjPLAYER@> contenders;
for (uint i = 0; i < 32; ++i) {
const jjPLAYER@ possible = jjPlayers[i];
if (possible.isInGame && possible.team == TEAM::BLUE) {
if (possible.roasts < minimumRoasts) {
minimumRoasts = possible.roasts;
contenders.resize(0);
}
if (possible.roasts == minimumRoasts) { //including the above case
contenders.insertLast(possible);
}
}
}
if (contenders.length != 0) {
const jjPLAYER@ loser = contenders[jjRandom() % contenders.length];
if (AtLeastOneRoast)
jjAlert(loser.name + " had the fewest roasts...", true, STRING::MEDIUM);
jjChat("/swap " + (loser.playerID + 1) + " red");
}
}
}
}
}
uint TimeTopLeft = 0;
void onPlayer(jjPLAYER@ player) {
if (player.health > 0 && int(player.xPos) / 32 <= 0 && int(player.yPos) / 32 <= 0 && player.warpID == 0) {
if (++TimeTopLeft % 280 == 250) {
for (int x = jjLayerWidth[4]; --x >= 0;)
for (int y = jjLayerHeight[4]; --y >= 0;) {
const uint8 event = jjEventGet(x,y);
if (event == AREA::JAZZSTART || event == AREA::MPSTART) {
player.warpToTile(x,y);
return;
}
}
}
} else TimeTopLeft = 0;
}
Jazz2Online © 1999-INFINITY (Site Credits). We have a Privacy Policy. Jazz Jackrabbit, Jazz Jackrabbit 2, Jazz Jackrabbit Advance and all related trademarks and media are ™ and © Epic Games. Lori Jackrabbit is © Dean Dodrill. J2O development powered by Loops of Fury and Chemical Beats.
Eat your lima beans, Johnny.