JazzJackrabbit Community Forums

JazzJackrabbit Community Forums (http://www.jazz2online.com/jcf/index.php)
-   JCS & Scripting (http://www.jazz2online.com/jcf/forumdisplay.php?f=5)
-   -   JJ2 AngelScript Presets! (http://www.jazz2online.com/jcf/showthread.php?t=19491)

FawFul Feb 1, 2013 05:12 AM

JJ2 AngelScript Presets!
 
Hello everyone, I'm starting this official thread to collect some easy preset codes for jj2's AngelScript so people won't have to make it over and over. It's also a tool to help new people understand seperately without being overwhelmed by really big scripts. only post basic preset scripts please, without much addition. for example, my script about giving a random power up to random players. I'm not adding all kinds of gimmicks like 3% chance of shield and fastfire, unlimited ammo on certain weapons and so on: keep it basic / editable.

Everyone is free to post Angelscripts here that quoted. I will try to compile them in this newspost. I made up a few categories myself (name more if you like). Also make sure your code works well. Text covered in red will be the variables you change



Weapon and firing related
Code:

Full Ammo randomizer #1 - Cooba (works multiple times)

int num;

void onFunction0() {
        num = (jjRandom()%9) + 1;
            p.powerup[num] = true;
            p.currWeapon = num;
            if (num > 1) p.ammo[num] = 50;
            switch (num) {
                    case 1: p.showText("§1#@@@@@@||||||||B|||||||L|||||||A|||||||S|||||||T|||||||E|||||||R|||||||!"); break;
                    case 2: p.showText("§1#@@@@@@||||B||||O||U||||N||C||||E||R||||!"); break;
                    case 3: p.showText("§1#@@@@@@||||I|||C|||E|||!"); break;
                    case 4: p.showText("§1#@@@@@@||||S||||||||E||||||EK||||||ER|||||||!"); break;
                    case 5: p.showText("§1#@@@@@@|||R|||||||F|||||||!"); break;
                    case 6: p.showText("§1#@@@@@@||||T||||||OA||||||ST||||||ER||||||!"); break;
                    case 7: p.showText("§1#@@@@@@|||T|N|||||T|!"); break;
                    case 8: p.showText("§1#@@@@@@|||||P|E|||||P|P|||||E|R|||||! |||||||o||r ||||F|I|||||R|E|||||B|A|||||L|L|||||!"); break;
                    case 9: p.showText("§1#@@@@@@|||||E|||||||L|||||||E|||||||C|||||||T|||||||R|||||||O |||||||B|||||||L|||||||A|||||||S|||||||T|||||||E|||||||R|||||||!"); break;
            }
}


Full Ammo randomizer #2 - FawFuL (works one time till death)

void onFunction0() {
        if (p.health != 0) {
                switch(jjRandom()%9) {
                          case 0: p.powerup[1] = true;
                                p.showText("§1#@@@@@@||||||||B|||||||L|||||||A|||||||S|||||||T|||||||E|||||||R|||||||!");
                                p.currWeapon = WEAPON::BLASTER; break;
                          case 1: p.ammo[2]=50;
                                p.powerup[2] = true;
                                p.showText("§1#@@@@@@||||B||||O||U||||N||C||||E||R||||!");
                                p.currWeapon = WEAPON::BOUNCER; break;
                          case 2: p.ammo[3]=50;
                                p.powerup[3] = true;
                                p.showText("§1#@@@@@@||||I|||C|||E|||!");
                                p.currWeapon = WEAPON::ICE; break;
                          case 3: p.ammo[4]=50;
                                p.powerup[4] = true;
                                p.showText("§1#@@@@@@||||S||||||||E||||||EK||||||ER||||||S!");
                                p.currWeapon = WEAPON::SEEKER; break;
                          case 4: p.ammo[5]=50;
                                p.powerup[5] = true;
                                p.showText("§1#@@@@@@|||R|||||||F|||||||!");
                                p.currWeapon = WEAPON::RF; break;
                          case 5: p.ammo[6]=50;
                                p.powerup[6] = true;
                                p.showText("§1#@@@@@@||||T||||||OA||||||ST||||||ER||||||!");
                                p.currWeapon = WEAPON::TOASTER; break;
                          case 6: p.ammo[7]=50;
                                p.showText("§1#@@@@@@|||T|N|||||T|!");
                                p.currWeapon = WEAPON::TNT; break;
                          case 7: p.ammo[8]=50;
                                p.powerup[8] = true;
                                p.showText("§1#@@@@@@|||||P|E|||||P|P|||||E|R|||||!  |||||||o||r  ||||F|I|||||R|E|||||B|A|||||L|L|||||!");
                                p.currWeapon = WEAPON::GUN8; break;
                          case 8: p.ammo[9]=50;
                                p.powerup[9] = true;
                                p.showText("§1#@@@@@@|||||E|||||||L|||||||E|||||||C|||||||T|||||||R|||||||O |||||||B|||||||L|||||||A|||||||S|||||||T|||||||E|||||||R|||||||!");
                                p.currWeapon = WEAPON::GUN9; break;
                        }
                }
        }
}

void onPlayer() {
        if (p.health == 0) jjEnabledASFunctions[TextID Variable] = true; //Unvanishes Textstring 0, Works again upon respawning
}

Object related
Code:

-
Animation related
Code:

-
Sound related
Code:

-
Pallette and Light related
Code:

Day and Night cycle - Sir Elementaler

const uint dnCYCLELENGTH=700; // Day Length.
const uint dnEVERYXTICKS=4; //the amount ticks the pallette refreshes it's colours.
const uint dnINITIALTICKS=256; //determines the initial time of the day. 0 means dawn, 256 means noon, 512 means dusk, 768 means midnight and 1024 means dawn again. All values allowed.
const string dnNIGHTTILESET="Carrot1N.j2t"; // the name of the tileset whose palette should be used in midnight.
jjPAL PaletteNight;

void onLevelLoad()
{
  PaletteNight.load(dnNIGHTTILESET);
}

void onMain()
{
  if(jjGameTicks%dnEVERYXTICKS==0)
  {
    jjPalette=PaletteNight;
    jjPalette.copyFrom(2,252,2,jjBackupPalette,(jjSin(1024*jjGameTicks/dnCYCLELENGTH+dnINITIALTICKS)+1)/2);
    jjPalette.apply();
  }
}

Layer (speed) related
Code:

-
SP and RPG (story) related
Code:

-
Physics and Character changes related
Code:

-
Area & Trigger related
Code:

Punish campers - Grytolle

/** script settings **/
const uint checkCampInterval=80;                  //how often to check for camping (gameticks)
/*********************/

/** level settings: define camp areas **/
array>> 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 time(gameticks)
        {{29,12},                {40,12},              {500}},      //camparea #0: on top of seek pu
        {{64,05},                {101,19},            {500}}      //camparea #1: the rf area
};
//it doesn't seem like you can have mixed arrays in AS
//so we just put the strings in a separatr array
array campAreaName = {                         
  "above seeks",                                                  //camparea #0
  "in the rf area"                                                  //camparea #1
};
/******** end of level settings ********/

/** script globals **/
const uint campAreas = campArea.length(); //save the number of campAreas for easy reference
array campTime(campAreas,0);                  //initialize campTime for all areas as 0 gameticks
/********************/


/** 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 isInCampArea(int player, int camparea) {        //use an array to return multiple bools
        array returnThis = {false, false};                        //we assume that the player is not camping
                                                                        //      (and not for too long)
        int maxCamp = campArea[camparea][2][0];                                //store a bunch of information in temporary
        int xCamp = campArea[camparea][0][0];                                //variables for easier reading
        int aCamp = campArea[camparea][1][0];
        int yCamp = campArea[camparea][0][1];
        int bCamp = campArea[camparea][1][1];
        int xPos = jjPlayers[player].xPos / 32;
        int yPos = jjPlayers[player].yPos / 32;

        if ((xPos >= xCamp)&&(xPos <= aCamp)&&(yPos >= yCamp)&&(yPos <= bCamp)) {  //is player in camparea?
          campTime[camparea] += checkCampInterval;
          returnThis[0] = true;                                                                                                    //set bool is camping
          jjPlayers[player].showText("You are camping " + campAreaName[camparea]); //display text (looks stupid if
          if (maxCamp < campTime[camparea]) {                                        // camping is checked too often)
                  returnThis[1] = true;                                                                                            //set bool camped for too long
          }
        }
        else campTime[camparea] = 0;                                                                                            //player not camping -> reset timer

        return returnThis;                                                                                                                    //return the (possibly altered) bool
}

/** You guys know what this one does already! **/
void onPlayer() {
        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 isCamping = isInCampArea(p.localPlayerID, i);                //check player and area, store result
                        if (isCamping[0]) {                                                                                                //is current player in camparea #1?
                                if (isCamping[1]) {                                                                                  //has current player been there for too long?
                                        jjChat("I camped for too long " + campAreaName[i] + ". Now I die :c");
                                        p.health = 0;                                                                                        //kill the player
                                        campTime[i] = 0;                                                                                //reset timer
                                }
                        }
                }
        }
}


cooba Feb 1, 2013 05:33 AM

Great idea for a thread.

Allow me to submit my own ammo randomizer, though! Not that anything is technically wrong with Faw's (very good and ambitious first script), of course.

Code:

int num;

void onFunction0() {
        num = (jjRandom()%9) + 1;
            p.powerup[num] = true;
            p.currWeapon = num;
            if (num > 1) p.ammo[num] = 50;
            switch (num) {
                    case 1: p.showText("§1#@@@@@@||||||||B|||||||L|||||||A|||||||S|||||||T|||||||E|||||||R|||||||!"); break;
                    case 2: p.showText("§1#@@@@@@||||B||||O||U||||N||C||||E||R||||!"); break;
                    case 3: p.showText("§1#@@@@@@||||I|||C|||E|||!"); break;
                    case 4: p.showText("§1#@@@@@@||||S||||||||E||||||EK||||||ER|||||||!"); break;
                    case 5: p.showText("§1#@@@@@@|||R|||||||F|||||||!"); break;
                    case 6: p.showText("§1#@@@@@@||||T||||||OA||||||ST||||||ER||||||!"); break;
                    case 7: p.showText("§1#@@@@@@|||T|N|||||T|!"); break;
                    case 8: p.showText("§1#@@@@@@|||||P|E|||||P|P|||||E|R|||||! |||||||o||r ||||F|I|||||R|E|||||B|A|||||L|L|||||!"); break;
                    case 9: p.showText("§1#@@@@@@|||||E|||||||L|||||||E|||||||C|||||||T|||||||R|||||||O |||||||B|||||||L|||||||A|||||||S|||||||T|||||||E|||||||R|||||||!"); break;
            }
}


FawFul Feb 1, 2013 07:33 AM

I would really love to see a Respawn trigger crate script for any ID explained, short and with variables!

Grytolle Feb 1, 2013 07:55 AM

Maybe this should be done on ERE? Or is the wiki too broken?

Stijn Feb 1, 2013 08:16 AM

Working on a code snippet section for J2O as we speak. Of course, as usual with whatever I'm working on, no ETA.

Meanwhile, if you have any feature requests for such a thing already, post them here.

FawFul Feb 1, 2013 08:31 AM

I want something else than JCF for this too, something easier to look over and with search functions. Meanwhile, best is to use this till there is another solution.

Violet CLM Feb 1, 2013 10:11 AM

Quote:

Originally Posted by FawFul (Post 477881)
I would really love to see a Respawn trigger crate script for any ID explained, short and with variables!

Two notes:

1) Trigger crates only query their Trigger ID when they're destroyed, so it's a question of the xOrg/yOrg bitfeld, not setting some other property to the desired ID.
2) Unless you're doing a single player level, you should probably use a generator object instead, so that the trigger crate is shared throughout the server. Otherwise you run the risk of the crate only existing locally and thus only changing a trigger locally.

If you still want such a script, though, I'd be tempted to do something like this pseudocode:

Code:

class myTriggerCrateGenerator:
  uint16 xOrg;
  uint16 yOrg;
  uint respawnCounter = 0;
  uint respawnDelay;
  int object = 0;
  void myTriggerCrateGenerator(uint16 x, uint16 y, uint d) {
    xOrg = x*32; yOrg = y*32; respawnDelay = d;
  }
  void do() {
    switch (respawnCounter) {
      case 0:
        jjOBJ@ o = jjObjects[object];
        if (!(o.isActive && o.eventID == OBJECT::TRIGGERCRATE && o.xOrg == xOrg && o.yOrg == yOrg))
          respawnCounter = 1;
        break;
      case respawnDelay: //this doesn't work, but in pseudo-code it does!
        respawnCounter = 0;
        object = jjAddObject(OBJECT::TRIGGERCRATE, xOrg, yOrg);
        break;
      default:
        ++respawnCounter;
    }
  }

And then have an array of myTriggerCrateGenerator objects and call do() on each of them every tick. But this is really just reinventing the wheel.

FawFul Feb 1, 2013 01:39 PM

Quote:

Originally Posted by Violet CLM (Post 477887)
Two notes:

1) Trigger crates only query their Trigger ID when they're destroyed, so it's a question of the xOrg/yOrg bitfeld, not setting some other property to the desired ID.
2) Unless you're doing a single player level, you should probably use a generator object instead, so that the trigger crate is shared throughout the server. Otherwise you run the risk of the crate only existing locally and thus only changing a trigger locally.

If you still want such a script, though, I'd be tempted to do something like this pseudocode:

And then have an array of myTriggerCrateGenerator objects and call do() on each of them every tick. But this is really just reinventing the wheel.

I've seen respawning trigger crates in JCSisFUN.

The thing i just want is to regenerate any trigger crate ID that is not just ID 31 that also works in MP (as in works as well as a normal trigger crate). I've never scripted before this update, i also have no idea what psuedo-code is. I just keep wondering if this is possible for MP, and i still haven't got clear answers yet.

Stijn Feb 1, 2013 01:53 PM

http://en.wikipedia.org/wiki/Pseudocode

Seren Feb 1, 2013 03:58 PM

Quote:

Originally Posted by Foly (Post 477878)
A function that converts an integer variable to a string:

Code:

string IntToStr(int Input) {
        int Number = Input;
        string tempstr;
        tempstr = "";
        while (Number > 0) {
                switch (Number % 10) {
                        case 0: tempstr = "0" + tempstr; break;
                        case 1: tempstr = "1" + tempstr; break;
                        case 2: tempstr = "2" + tempstr; break;
                        case 3: tempstr = "3" + tempstr; break;
                        case 4: tempstr = "4" + tempstr; break;
                        case 5: tempstr = "5" + tempstr; break;
                        case 6: tempstr = "6" + tempstr; break;
                        case 7: tempstr = "7" + tempstr; break;
                        case 8: tempstr = "8" + tempstr; break;
                        case 9: tempstr = "9" + tempstr; break;
                }
                Number = Number/10;
        }
        if (tempstr == "")
                tempstr = "0";
        return tempstr;
}


I... don't want to play smart ass or anything, but I know a slightly shorter piece of code for that:
Code:

formatInt(value,"l");

Violet CLM Feb 1, 2013 04:29 PM

Quote:

Originally Posted by FawFul (Post 477888)
I've seen respawning trigger crates in JCSisFUN.

The thing i just want is to regenerate any trigger crate ID that is not just ID 31 that also works in MP (as in works as well as a normal trigger crate). I've never scripted before this update, i also have no idea what psuedo-code is. I just keep wondering if this is possible for MP, and i still haven't got clear answers yet.


Set "Initial Delay" to 1 on the upper-right MCE Event for best results. This is what I would have done in that level, but cooba thought doing it through AngelScript would be clearer than using a MCE as pictured. If you want something multiplayer-friendly, use an MCE.

That said, I have an idea for how AngelScript might be able to make it easier, so watch this space.

Foly Feb 2, 2013 12:06 AM

Quote:

Originally Posted by Sir Ementaler (Post 477892)
I... don't want to play smart ass or anything, but I know a slightly shorter piece of code for that:
Code:

formatInt(value,"l");

Yes, i tried that one too but it didn't work for me :(
Either i did it wrong or it isn't build in with jj2+.

Seren Feb 2, 2013 02:37 AM

I hadn't been sure either so I had checked it before I posted that, it works just fine. Try something like this (in multiplayer) to test:
Code:

void onPlayer()
{
  jjChat(formatInt(jjGameTicks,"l"));
}


Foly Feb 2, 2013 02:43 AM

Quote:

Originally Posted by Sir Ementaler (Post 477897)
I hadn't been sure either so I had checked it before I posted that, it works just fine. Try something like this (in multiplayer) to test:
Code:

void onPlayer()
{
  jjChat(formatInt(jjGameTicks,"l"));
}


Oh, i made a mistake then, sorry. Thanks for noticing, it's always better to have shorter codes :)

Grytolle Feb 2, 2013 03:49 AM

I found this for syntax highlighting of AngelScript in Notepad++.

I just dropped it in the program folder\plugins\APIs, and then I am able to select it for a specific file by clicking Language -> AngelScript. It would be nicer if it could be made so that it automatically identifies .j2as files as AngelScript, but I couldn't get it to work and I'm not really intending to try coding anything myself at the moment, so I'll leave that up to you.

AngelScript syntax highlighting

FawFul Feb 2, 2013 06:46 AM

Quote:

Originally Posted by Violet CLM (Post 477893)

Set "Initial Delay" to 1 on the upper-right MCE Event for best results. This is what I would have done in that level, but cooba thought doing it through AngelScript would be clearer than using a MCE as pictured. If you want something multiplayer-friendly, use an MCE.

That said, I have an idea for how AngelScript might be able to make it easier, so watch this space.

Thanks a lot! Now i only need a way to turn it off to 0 with this.

Violet CLM Feb 2, 2013 10:31 AM

Add 32 to the leftmost MCE Event's "Event" parameter to make it act as an Off crate, or 64 to make it act as a Switch crate.

Seren Feb 2, 2013 11:03 AM

Day / night cycle
This script will smoothly change tileset palette between day and night. If used in multiplayer, it works for every client locally, meaning that each client will see a different time of the day.
Code:

const uint dnCYCLELENGTH=700;
const uint dnEVERYXTICKS=4;
const uint dnINITIALTICKS=256;
const string dnNIGHTTILESET="Carrot1N.j2t";
jjPAL PaletteNight;

void onLevelLoad()
{
  PaletteNight.load(dnNIGHTTILESET);
}

void onMain()
{
  if(jjGameTicks%dnEVERYXTICKS==0)
  {
    jjPalette=PaletteNight;
    jjPalette.copyFrom(2,252,2,jjBackupPalette,(jjSin(1024*jjGameTicks/dnCYCLELENGTH+dnINITIALTICKS)+1)/2);
    jjPalette.apply();
  }
}

  • dnCYCLELENGTH determines length of a single cycle in game ticks. 70 means one second.
  • dnEVERYXTICKS determines how often the palette should be updated. 1 will give the smoothest effect but can slow down the game. Higher values will save memory but not look as nice.
  • dnINITIALTICKS determines the initial time of the day. 0 means dawn, 256 means noon, 512 means dusk, 768 means midnight and 1024 means dawn again (there will be no difference between setting this constant to 0 and 1024). Of course, values in between are also allowed.
  • dnNIGHTTILESET is name of the tileset whose palette should be used in midnight. Note that the noon palette will be set to the default tileset of the level.
Healing freezer
In team games, this script will let players heal their teammates by shooting ice bullets at them. A single bullet can heal multiple people. Each bullet will heal 1 heart of damage. If freezer is powered-up, it shoots two bullets, so if both hit a player, it heals 2 hearts of damage in total. It won't heal the person who shot the bullet nor members of the opposite team.
Code:

void onPlayer()
{
  for (int i=1;i<jjObjectCount;i++)
  {
    if(jjObjects[i].isActive&&(jjObjects[i].eventID==OBJECT::ICEBULLET||jjObjects[i].eventID==OBJECT::ICEBULLETPU))
    {
      if(jjObjects[i].xPos>p.xPos-12
      &&jjObjects[i].xPos<p.xPos+12
      &&jjObjects[i].yPos>p.yPos-12
      &&jjObjects[i].yPos<p.yPos+12
      &&jjObjects[i].state!=STATE::KILL
      &&jjPlayers[jjObjects[i].creator].playerID!=p.playerID
      &&jjPlayers[jjObjects[i].creator].teamRed==p.teamRed)
      {
        if(p.health<jjMaxHealth)
        {
          p.health=p.health+1;
        }
        jjObjects[i].state=STATE::KILL;
      }
    }
  }
}

This script has no properties to edit.

Toni_ Feb 3, 2013 01:32 AM

I would appreciate if someone writes a script that:

1) Makes text on text events not bouncing, or bouncing even more.
2) Changing direction of text on text events appearing. (Default is from right to left)
3) Makes it appear on different horizontal line.

Grytolle Feb 3, 2013 06:16 AM

Just A Random User: I am pretty sure that such functions first need to be implemented in plus.dll, not really anything that a script can solve.

Punish campers xd!
This was the first thing I could think of when I wanted to try out AngelScript, but it could probably be altered quite easily for trigger-like purposes or something. It also illustrates the use of (multi-layered) arrays and return in conjunction with an array.

semi.j2as:
Pastebin'd for easier reading

Code:

old code removed to save space
Edit: Please read the code on pastebin, because things like "" gets treated as html code here.
Edit2: It would make more sense to execute jjPlayers[player].showText("You are camping " + campAreaName[camparea]); outside of the function. If there are more improvements that will have to be made, I will work that into the next version. :P

Jerrythabest Feb 3, 2013 06:55 AM

Oh NICE Grytolle! That one's REALLY awesome :D

Toni_ Feb 3, 2013 09:58 AM

Punishment should be -1h. Killing a player sounds too severe. If I use this script, will this work for -1h punishment?

Code:

if (isCamping[1])
{
    jjChat("I camped for too long " + campAreaName[i] + ". Now I get punishment");
    p.health = p.health - 1;
    campTime[i] = 0;
}


Grytolle Feb 3, 2013 10:44 AM

Quote:

Originally Posted by Just a Random User (Post 477935)
Punishment should be -1h. Killing a player sounds too severe. If I use this script, will this work for -1h punishment?

Code:

if (isCamping[1])
{
    jjChat("I camped for too long " + campAreaName[i] + ". Now I get punishment");
    p.health = p.health - 1;
    campTime[i] = 0;
}


Yes, that would work, but you might be able to write it shorter like this:
Code:

p.health -= 1;
I've made a new version of the script, however. In this version, you'd need to use this:
Code:

jjPlayers[pID].pHealth -= 1;
//or
jjPlayers[pID].pHealth = jjPlayers[pID].pHealth - 1;

----------

Please use pastebin to see everything properly: http://pastebin.com/fwQ1Q3b9
Code:

saving space

Seren Feb 3, 2013 10:46 AM

Quote:

Originally Posted by Grytolle (Post 477928)
Just A Random User: I am pretty sure that such functions first need to be implemented in plus.dll, not really anything that a script can solve.

You need to be more open-minded. It can be done with a script. I could do it myself but it's very highly complicated and requires a lot of time, while I have many other scripts to write. Also, I'm afraid it would be limited to about 100 characters on screen.

Violet CLM Feb 3, 2013 11:24 AM

Quote:

Originally Posted by Grytolle (Post 477936)
]jjPlayers[pID].pHealth -= 1;

Doesn't work, unfortunately. Health is one of a number of properties that are actually pairs of get_health/set_health methods being passed off as simple properties, and -=/+=/--/++ don't work on those.

SE, are you proposing drawing text manually by creating objects with individual characters as their sprites? If so, that's very resourceful, but eww.

Seren Feb 3, 2013 11:47 AM

Quote:

Originally Posted by Violet CLM (Post 477938)
SE, are you proposing drawing text manually by creating objects with individual characters as their sprites?

MAYBE

[IMG]http://img845.imageshack.us/img845/5228/seas1.png[/IMG]

But hey, for short enough strings it works!

Jerrythabest Feb 3, 2013 01:38 PM

I figure we could provide API access to the drawText series of functions, so people can write their own UI elements. By doing it that way such elements would benefit from the fact that someday I'll implement 3D support for the UI itself, which will mostly happen in the drawText stuff.

Grytolle Feb 3, 2013 03:05 PM

Quote:

Originally Posted by Jerrythabest (Post 477944)
I figure we could provide API access to the drawText series of functions, so people can write their own UI elements. By doing it that way such elements would benefit from the fact that someday I'll implement 3D support for the UI itself, which will mostly happen in the drawText stuff.

That would be great!

Made a new version where you can define several rectangles to form one camp area (see id #3, the seekbox on semi).

Illustrating what tiles are marked:
[img]http://jazzjackrabbit.net/gry/camparea.png[/img]
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.0
http://pastebin.com/XBQhpkAK (as always, please read it on pastebin)
Code:

/*
Punish campers xd! v2.0

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:
-make it not needed to state maxcamp for every sub-area
-show time remaining in campspot (could be achieved with the timer functions, I assume)
-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=70;                  //how often to check for camping (gameticks) 70 = one second
/*********************/

/** level settings: define camp areas **/
array>> 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},                {40,12},              {250},                        {0}},              //camparea #0: on top of seek pu
        {{64,05},                {101,19},            {500},                        {1}},              //camparea #1: the rf area
        {{30,49},                {64,56},                {250},                        {2}},                //camparea #2: at carrot

        {{31,14},                {41,14},                {250},                        {3}},                //camparea #3: rectangle1
        {{30,15},                {41,15},                {250},                        {3}},                //camparea #3: rectangle2
        {{30,16},                {41,16},                {250},                        {3}},                //camparea #3: rectangle3
        {{31,17},                {41,17},                {250},                        {3}},                //camparea #3: rectangle4
        {{32,18},                {39,18},                {250},                        {3}},                //camparea #3: rectangle5
        {{35,19},                {38,19},                {250},                        {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 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 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 isInCampArea(int pID, int camparea) {        //use an array to return multiple bools
        //if (camparea == 3) jjDebug("checking area #" +  formatInt(camparea,"l"));
        array returnThis = {false, false};                        //we assume that the player is not camping
                                                                        //      (and not for too long)

        int maxCamp;
        int xPos = jjPlayers[pID].xPos / 32;
        int yPos = jjPlayers[pID].yPos / 32;
        campTime[camparea] += checkCampInterval;                                                                        //update camptime
                                                                                                       
        for (uint j=0; j < campAreasRealLength;j++) {                               
                if (campArea[j][3][0] == camparea)  {                        //all parts of the camp area
                        //jjDebug("camp #" + formatInt(j,"l"));
                        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]) {
                campTime[camparea] = 0;                                                                                            //player not camping -> reset timer
                //if (camparea == 3) jjDebug("not camping #" + formatInt(camparea,"l"));
        }
        /*else {
                if (camparea == 3)jjDebug("is camping" + formatInt(camparea,"l"));
        }*/
        if (maxCamp < campTime[camparea]) {                                       
                returnThis[1] = true;                                                                                            //set bool camped for too long
        }
       
       
       
       
       
        return returnThis;                                                                                                                    //return the (possibly altered) bool
}

/** onPlayer wouldn't work for me ;S **/
void realOnPlayer(int pID) {
        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 isCamping = isInCampArea(pID, i);                                                                //check player and area, store result
                        if (isCamping[0]) {                                                                                                                        //is current player in camparea #1?
                                jjPlayers[pID].showText("You are camping " + campAreaName[i]);                        //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
                                        /**                          ^-^                          **/
                                       
                                }
                        }
                }
        }
}
void onMain() {
        /** emulating onPlayer **/
        for (uint i=0; i < 32;i++) {
                if ((jjPlayers[i].isActive)&&(jjPlayers[i].isLocal)) realOnPlayer(i);
        }
        /************************/
}


Stijn Feb 3, 2013 03:20 PM

http://www.jazz2online.com/snippets/

Quick and dirty, but seems to work. Will make it look more fancy later. Feature requests and bug reports are possible, can't say much about when they'd be addressed though.

Grytolle Feb 3, 2013 03:29 PM

Seems to work well, except that the version number didn't increase :)

Stijn Feb 3, 2013 03:34 PM

Yeah, as usual all kinds of bugs appear when someone uses it for something else than testing ;)

djazz Feb 3, 2013 03:42 PM

Here's my blade gun!
http://www.youtube.com/watch?v=Qr8pahz-QTs

Pastebin: http://pastebin.com/5WYsBEQT
It's also on the snippets page, here: http://www.jazz2online.com/snippets/...troblaster-pu/

Stijn Feb 3, 2013 04:47 PM

Quote:

Originally Posted by Grytolle (Post 477953)
Seems to work well, except that the version number didn't increase :)

Fixed this, and also added a "raw code" button to pages to go to a plaintext version of the source code. The highlighted code is also a bit more readable, though there's only so much you can do with Gry's coding style ;)

Seren Feb 3, 2013 10:30 PM

Quote:

Originally Posted by Stijn (Post 477957)
added a "raw code" button to pages to go to a plaintext version of the source code.

Oh nice, that and ctrl+A solves the issue as was lack of a "select the whole code" button that I didn't even have time to mention yet.

Violet CLM Feb 4, 2013 12:07 AM

DJazz, mind if I put that blade gun video on the Mod DB page? It's pretty cool-looking.

djazz Feb 4, 2013 12:51 AM

Quote:

Originally Posted by Violet CLM (Post 477963)
DJazz, mind if I put that blade gun video on the Mod DB page? It's pretty cool-looking.

Sure thing! :D

DennisKainz Feb 4, 2013 09:42 AM

I'm making a little SP level, and I have made a little part of the script...

void onLevelLoad() { jjObjectPresets[OBJECT::NORMTURTLE].energy = 8; jjObjectPresets[OBJECT::BEE].energy = 8; jjObjectPresets[OBJECT::TURTLESHELL].energy = 32; }
void onMain() { p.food = 99; if (p.health > 1) p.health = 1; }

I managed to make some enemies health x8, emulate the Instagib command, and make Jazz get the sugar rush with one only food item (would help a lot in the Jazz Unleashed Hell level), but I have spent a whole unsuccesful hour trying to make an expression for me to have as the level completing goal to kill every single enemy and collect every single item.

I tried "if (OBJECT::NORMTURTLE = 0)", "if (OBJECT::NORMTURTLE.state = STATE::KILL)", "if (OBJECT::NORMTURTLE.jjObjectCount = 0)" but they all crashed the j2as file instead. Can anyone help me here?

Violet CLM Feb 4, 2013 12:06 PM

Hmmm. That's a tricky one, because SP doesn't store jjOBJ copies of objects that aren't near to the player. It's only in MP that you get jjOBJs for everything all the time. But there might still be a solution...
Code:

bool areAllNormTurtlesDestroyed() {
  jjOBJ@ o;
  for (int i = 1; i < jjObjectCount; ++i) {
    @o = jjObjects[i];
    if (o.isActive && o.eventID == OBJECT::NORMTURTLE) return false;
  }
  for (uint16 x = 0; x < jjLayerWidth[4]; ++x) {
    (for uint16 y = 0; y < jjLayerHeight[4]; ++y) {
      if (jjEventGet(x,y) == OBJECT::NORMTURTLE && jjParameterGet(x,y,-1,1) == 0) return false;
    }
  }
  return true;
}

The key step is jjParameterGet(x,y,-1,1), which is a bit that is set to 1 in the event field when an object is created. The bit is set back to 0 if the object passes off screen and gets deactivated, but it is left at 1 if you destroy the object. Basically, if it's at 0 JJ2 takes that as a cue to create the object when that tile is close enough to the player -- if it's at 1, JJ2 ignores it. So that code might work, unless there's something else I'm not thinking of.

Grytolle Feb 4, 2013 02:50 PM

Notice: Undefined variable: oPackage in /home/jazzonli/public_html/J2Ov2/snippets/form.php on line 29

Fatal error: Call to a member function info() on a non-object in /home/jazzonli/public_html/J2Ov2/snippets/form.php on line 29

: (

Stijn Feb 4, 2013 03:43 PM

Should be fixed


All times are GMT -8. The time now is 01:37 PM.

Powered by vBulletin® Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
JCF © 2001-Infinity Jazz2Online