| 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");
}
}
}
int RectangleFrameIDs;
void onLevelLoad() {
uint8 customSetID = 0;
while (jjAnimSets[ANIM::CUSTOM[customSetID]] != 0) { ++customSetID; }
RectangleFrameIDs = jjAnimations[jjAnimSets[ANIM::CUSTOM[customSetID]].allocate(array<uint>={100})];
//jjAlert("" + RectangleFrameIDs);
jjPIXELMAP rectangle(1,10);
for (uint y = 0; y < 10; ++y)
rectangle[0,y] = 25 + (y + 1) / 4;
auto rectangleFrameID = RectangleFrameIDs;
for (uint i = 0; i < 100; ++i) {
jjANIMFRAME@ frame = jjAnimFrames[rectangleFrameID++];
frame.hotSpotY = 3;
rectangle.resize(i + 1, 10).addBorders(0,0,1,0).save(frame);
rectangle.addBorders(0,0,-1,0);
}
}
array<int> Timers(32, 200);
bool onDrawGameModeHUD(jjPLAYER@, jjCANVAS@ canvas) { 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");
}
}
}
}
for (uint playerID = 0; playerID < 32; ++playerID) {
jjPLAYER@ player = jjPlayers[playerID];
player.iconSet(player.isInGame && Timers[playerID] >= 2 ? jjAnimFrames[RectangleFrameIDs + Timers[playerID] / 2 - 1] : null, player.teamRed ? 0 : 8);
}
}
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;
}
void onHelp(array<jjHELPPAGE@>& pages) {
for (int i = pages.length - 1; i >= 0; --i) { //remove any existing pages with the gamemode tag
if (jjRegexSearch(pages[i].tags, "\\bgamemode\\b", true))
pages.removeAt(i);
}
pages.insertLast(jjHELPPAGE(
{
jjHELPPARAGRAPH(
"||Con|demned",
textSize: STRING::MEDIUM,
textAlignment: STRING::CENTER
),
jjHELPPARAGRAPH(
"One or more players are placed randomly on the \\2red\\6 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 (\\2red\\6) player may roast a normal (\\3blue\\6) player to swap both their teams."
),
jjHELPPARAGRAPH(
"Best played with a low max health, so people die a lot.",
image: jjAnimFrames[RectangleFrameIDs + 99],
position: HELP::TOPCENTER
)
},
"mutator gamemode condemned"
));
if (jjIsServer || jjLocalPlayers[0].isAdmin)
pages.insertLast(jjHELPPAGE(
{
jjHELPPARAGRAPH("Host Condemned with \\4/pregame on\\6 or \\4/autostart off\\6, to give the game time to decide who should start on the red team. The game automatically stops once the winner has been determined, so you'll need to use \\4/c\\6 after that."),
jjHELPPARAGRAPH("For keeping track of scores for JDC-like purposes, search the server's chatlog for lines beginning with four asterisks (\\4****\\6).")
},
"mutator gamemode condemned commands",
"Commands"
));
}
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.