Punish campers! xd

Version:

4.0

Added on:

04 Feb 2013 13:27

Tags:

Description:
Illustrating what tiles are marked for camparea #3:



It was a bit tricky to select the right ones, because when you jump into a tile above you your head (atleast as spaz) sticks into it a bit (the right outer side of the seekbox). I also made a small alteration to the comparison code, changing (xPos <= aCamp) to (xPos < aCamp). Not sure why it's better, but trial and error tells me that it is so.
/*
Punish campers xd! v2.1

changes v2.1:
-made onPlayer work thanks to Violet
-made it not needed to state maxcamp for every sub-area
-added timer by letting the "you are camping" text show every second
-the "you are camping message" disappears when you stop camping
 in order for that to happen as soon as possible, I have lowered checkCampInterval to 10
 (you have to use something that 70 is evenly divisible with)

changes v2.0:
-made non-rectangular camp areas possible

changes v1.1:
-had to recreate the onPlayer function, because it wouldn't work for clients :S
-moved a message out of isInCampArea()
-killed player with .kill() instead of .health=0 (thx cooba)

improvements needed:
-don't kill players if the game is stopped (the AngelScript implementation needs a new bool)
-the chat is sent as teamchat if the player last used teamchat
-you regain health if you die on purpose with flag xd
*/

/** script settings **/
const uint checkCampInterval=10;      //how often to check for camping (gameticks) 70 = one second
/*********************/

/** level settings: define camp areas **/
array<array<array<int>>> campArea = {
 /* A camparea is a rectangle referred to by its top left and bottom right corner
x,y -----------
    |         |
    |         |
    ----------- a,b                                                              */
//  camparea(x,y)  camparea(a,b)  allowed camp  id 
                                 // time(gameticks) (needed for new shapes)
  {{29,12},     {41,12},        {280},      {0}},        //camparea #0: on top of seek pu
  {{64,05},     {101,19},       {490},      {1}},        //camparea #1: the rf area
  {{30,49},     {64,56},     {280},      {2}},    //camparea #2: at carrot
                  
                  //the script will only pay attention to the first camp time for the entire camparea id
  {{31,14},     {41,14},     {280},      {3}},     //camparea #3: rectangle1
  {{30,15},     {41,15},     {},        {3}},       //camparea #3: rectangle2
  {{30,16},     {41,16},     {},        {3}},       //camparea #3: rectangle3
  {{31,17},     {41,17},     {},        {3}},       //camparea #3: rectangle4
  {{32,18},     {39,18},     {},        {3}},       //camparea #3: rectangle5
  {{35,19},     {38,19},     {},        {3}}       //camparea #3: rectangle6
};
//it doesn't seem like you can have mixed arrays in AS
//so we just put the strings in a separate array
array<string> campAreaName = {        
  "above seeks",              //camparea #0
  "in the rf area",              //camparea #1
  "at the carrot",              //camparea #2
  "in the seek box"              //camparea #3
};
/******** end of level settings ********/

/** script globals **/
uint campAreas = 0;
uint campAreasRealLength;
array<int> campTime;


void onLevelLoad() {
  campAreasRealLength = campArea.length();
  for (uint i=0; i < campAreasRealLength;i++) {
    campAreas = campArea[i][3][0];
  }
  campAreas++;
  campTime.resize(campAreas);
}

/********************/


/** This function checks if a player is in a certain camparea        **/
/** and returns two bools: 1) whether the player is in the camp area **/
/** and 2) whether they have been there for too long                 **/
array<bool> isInCampArea(int pID, int camparea) {  //use an array<bool> to return multiple bools
  array<bool> returnThis = {false, false, false};      //we assume that the player is not camping 
                                                                   //      (and not for too long)

  int maxCamp = 0;
  int xPos = jjPlayers[pID].xPos / 32;
  int yPos = jjPlayers[pID].yPos / 32;
                          
  for (uint j=0; j < campAreasRealLength;j++) {        
    if (campArea[j][3][0] == camparea)  {      //all parts of the camp area
      
      if (maxCamp == 0) maxCamp = campArea[j][2][0];        //store a bunch of information in temporary                                  
      int xCamp = campArea[j][0][0];                //variables for easier reading
      int aCamp = campArea[j][1][0];
      int yCamp = campArea[j][0][1];
      int bCamp = campArea[j][1][1];
      
      if ((xPos >= xCamp)&&(xPos < aCamp)&&(yPos >= yCamp)&&(yPos <= bCamp)) {   //is player in camparea?
         returnThis[0] = true;                             //set bool is camping
      }
      
      }
  }
  
  
  if (!returnThis[0]) {
    if (campTime[camparea] > 0) {
      returnThis[2] = true; //was camping
    }
    campTime[camparea] = 0;                          //player not camping -> reset timer
  }
  else campTime[camparea] += checkCampInterval;                  //update camptime  

  if (maxCamp < campTime[camparea]) {                                        
    returnThis[1] = true;                           //set bool camped for too long
  }
  
  
  return returnThis;                                //return the (possibly altered) bool
}

void onPlayer() {
  int pID = p.playerID;
  if (jjGameTicks % checkCampInterval == 0) {                      //(thanks Artem/Foly)
    for (uint i=0; i < campAreas;i++) {                        //loop through all camp areas
        //^uint to avoid warning "Signed/Unsigned mismatch"
      array<bool> isCamping = isInCampArea(pID, i);                //check player and area, store result
      if (isCamping[0]) {                              //is current player in camparea #1?
        int remainingSecs = ((campArea[i][2][0] - campTime[i]) / 70);
        if (jjGameTicks % 70 == 0) jjPlayers[pID].showText("You are camping " + campAreaName[i] + ". Dead in " + formatInt(remainingSecs,"l") + " seconds.");       //display text (looks stupid if
                                              // camping is checked too often)
        if (isCamping[1]) {                             //has current player been there for too long?
        
          /** WHAT SHOULD HAPPEN IF THE PLAYER CAMPS FOR TOO LONG??? **/
          jjChat("I camped for too long " + campAreaName[i] + ". Now I die :c");
          jjPlayers[pID].kill();                        //kill the player
          campTime[i] = 0;                          //reset timer
          /**                          ^-^                           **/ 
          
        }
      }
      else {
        if (isCamping[2]) jjPlayers[pID].showText(" "); //was camping
      }
    }
  }
}