LTTPesque dark area.

I’ve spent almost 3 full days figuring this one out. The angles created by wall corners were hard to script as I had nooo idea what to do… my maths knowledge is really old.
Also, first time ever working with polygons.

So here’s a video.

[video=youtube;TTGRF2q2YyQ]https://www.youtube.com/watch?v=TTGRF2q2YyQ[/video]

This part makes the level completely dark and displays the flashlight.

[CODE]// NPC made by 2ndwolf
if (created) {
this.zoom = 1.2; //not functional
this.dists = {2,15,4.5,4.5};
this.playerwidth = 2;
timeout = .05;
}

if(timeout){
this.wobble = this.run%.05;
this.wobblehelp = 0;
if(playerdir==0){
this.axis={playery+this.playerwidth,playerx+this.p layerwidth/1.5};
this.direction = {-1,1};
this.redirect = {1,3,0,2};
}
else if(playerdir==1){
this.axis={playerx+this.playerwidth,playery+this.p layerwidth};
this.direction = {-1,1}
this.redirect = {2,0,3,1};
}
else if(playerdir==2){
this.axis={playery+this.playerwidth/1.5,playerx+this.playerwidth/1.5};
this.direction = {1,-1};
this.redirect = {0,2,1,3};
}
else if(playerdir==3){
this.axis = {playerx+this.playerwidth/1.5,playery+this.playerwidth};
this.direction = {1,-1};
this.redirect = {3,1,2,0};
}

this.coords = {this.axis[0]-(this.dists[0]*this.direction[0])*this.zoom,
this.axis[0]+(this.dists[1]*this.direction[0])*this.zoom,
this.axis[1]+(this.dists[2]*this.direction[0])*this.zoom,
this.axis[1]-(this.dists[3]*this.direction[0])*this.zoom};

if(playerdir==0){
  hideimg 905;
  showimg 906,erk_flashlightvert.png,this.coords[2],this.coords[1]+this.wobble;
 // showimg 907,erk_flashlightvertgradiant.png,this.coords[2],this.coords[1]+this.wobble;

// changeimgcolors 907,0,1,1,.5;
// changeimgmode 907,0;
}
else if(playerdir==1){
hideimg 906;
showimg 905,erk_flashlighthoriz.png,this.coords[1],this.coords[2]+this.wobble;
}
else if(playerdir==2){
hideimg 905;
showimg 906,erk_flashlightvert.png,this.coords[3],this.coords[0]+this.wobble;
}
else if(playerdir==3){
hideimg 906;
showimg 905,erk_flashlighthoriz.png,this.coords[0],this.coords[3]+this.wobble;
}
this.run+=.01;

// top poly
showpoly 901,{0,0,64,0,64,this.coords[this.redirect[0]]+this.wobblehelp,0,this.coords[this.redirect[0]]+this.wobblehelp};
//right poly
showpoly 902,{this.coords[this.redirect[1]]+this.wobblehelp,0,64,0,64,64,this.coords[this.redirect[1]]+this.wobblehelp,64};
//bottom poly
showpoly 903,{0,this.coords[this.redirect[2]]+this.wobblehelp,64,this.coords[this.redirect[2]]+this.wobblehelp,64,64,0,64};
//left poly
showpoly 904,{0,0,this.coords[this.redirect[3]]+this.wobblehelp,0,this.coords[this.redirect[3]]+this.wobblehelp,64,0,64};

changeimgcolors 901,0,0,0,1;
changeimgcolors 902,0,0,0,1;
changeimgcolors 903,0,0,0,1;
changeimgcolors 904,0,0,0,1;

timeout = 0.05;
}
[/CODE]

This part should be placed at every corner, topleftmost.
Nothing’s hardcoded so all you need to change are the coordinates.

[CODE]// NPC made by 2ndwolf
if (created) {

//You only need to change these coordinates 0 to 7.
////CLOCKWISE : TL TR BR BL ANG ANG ///
this.coords = { x,y,x+3,y,x+3,y+7,x,y+7, 51, 51 } ///
// 0,1, 2, 3, 4, 5, 6, 7, 8, 9 ///
//////////////////////////////////////////////////////////
this.imgid = 802;
timeout = 0.05;

}

if(timeout){

//HORIZONTAL
if(this.coords[0]-this.coords[2]<this.coords[3]-this.coords[5]){
this.playeraxis = {playerx,playery};
this.origin = {x,y};
//LEFT
if(this.playeraxis[0]<min(this.coords[0],this.coords[6])){
this.direction = {1,-1};
this.redir = {8,1,2,3,4,5,9,7,0,6};
this.crucial = {0,1,6,7};
// TL BL
//RIGHT
} else {
this.direction = {-1,1};
this.redir = {0,1,8,3,9,5,6,7,2,4};
this.crucial = {2,3,4,5};
}
}
//VERTICAL
else {
this.playeraxis = {playery,playerx};
this.origin = {y,x};
//TOP
if(this.playeraxis[0]<min(this.coords[1],this.coords[3])){
this.direction = {1,-1};
this.redir = {0,8,2,9,4,5,6,7,1,4};
this.crucial = {3,0,1,2};
//BOTTOM
} else {
this.direction = {-1,1};
this.redir = {0,1,2,3,4,9,6,8,5,7};
this.crucial = {7,6,5,4};
}
}

showpoly this.imgid,{
              this.coords[this.redir[0]],this.coords[this.redir[1]],      //TL
              this.coords[this.redir[2]],this.coords[this.redir[3]],      //TR
              this.coords[this.redir[4]],this.coords[this.redir[5]],      //BR
              this.coords[this.redir[6]],this.coords[this.redir[7]]};     //BT
changeimgcolors this.imgid,0,0,0,1;


if(this.playeraxis[1]>this.coords[this.crucial[3]]-1){
  this.regplayer = this.origin[1]+(-this.playeraxis[1])+6.5;
  this.coords[8] = this.coords[this.crucial[0]]+2^this.regplayer *this.direction[0];
  this.coords[9] = this.coords[this.crucial[2]];
}
else if (this.playeraxis[1]<this.coords[this.crucial[1]]-2){
  this.regplayer = 64-(this.origin[1]+(64-this.playeraxis[1]))+6.5;
  this.coords[8] = this.coords[this.crucial[0]];
  this.coords[9] = this.coords[this.crucial[2]]+2^this.regplayer *this.direction[0];
} else {
  hideimg this.imgid;
}

timeout = 0.05;
}[/CODE]

Here are the flashlight effect images:

pretty cool
I would’ve just made an inverse light and make it follow the player since I’m lazy

that around the corner shadow thing is fucking cool. zombie level action.

Downsider already made a better one that interestingly has the same corner shadow thing.

well where is it?

This is pretty cool, I made something similar except using onwall to detect corners and what not. Wouldn’t this get a bit laggy with the mass amount of npcs required in the level?

Light effects in general are laggy.

I realised that after posting… I was going to add a script that would automatically place the corner shadows but I was starting to get mad so I’ve just called it done. Complete enough.

by automatically place I assume you mean using putnpc? That won’t solve the issue as the same amount of npcs will be in the level whilst it’s running…

Lol, the corner thing looks so bad. Not necessarily your fault, just the way Graal’s shitty engine requires you to do it. This is one reason why a new one is needed.

// NPC made by tricxta
if (playerenters){
  replaceani idle,xialza_lamp_idle;
  replaceani walk,xialza_lamp_walk;
  seteffect 0,0,0.1,0.5;
  timereverywhere;
  noplayerkilling;
  this.quality = 10;

  this.lightRad = 20;//actually is the diameter

  timeout = 0.05;
}

if (timeout){
  setstring this.cRec,;
  //top left
  addstring this.cRec,0;
  addstring this.cRec,0;

  //top centre
  addstring this.cRec,#v(playerx);
  addstring this.cRec,0;

  for (this.degrees = 360; this.degrees >= 0; this.degrees-=this.quality){
    this.radians = (this.degrees/360)*(2*pi) - (pi/2);
    this.lightOnwall = 0;
    for (this.r = 0; this.r < (this.lightRad/2); this.r+= (this.quality/10)){
      this.sampleCoords = {playerx+1.5+cos(this.radians)*this.r,playery+1.5+sin(this.radians)*this.r};
      if (!lighteffectsenabled)continue;
      if (onwall(this.sampleCoords[0],this.sampleCoords[1])){
        this.lightOnwall = 1;
      }
      else if (this.lightOnwall == 1){
        this.r = this.lightRad;
      }
    }
    addstring this.cRec,#v(this.sampleCoords[0]);
    addstring this.cRec,#v(this.sampleCoords[1]);
  }

  //finish the loop
  addstring this.cRec,#I(this.cRec,4);
  addstring this.cRec,#I(this.cRec,5);

  //top centre
  addstring this.cRec,#v(playerx);
  addstring this.cRec,0;

  //top right
  addstring this.cRec,64;
  addstring this.cRec,0;

  //bottom right
  addstring this.cRec,64;
  addstring this.cRec,64;

  //bottom left
  addstring this.cRec,0;
  addstring this.cRec,64;

  setarray this.poly,sarraylen(this.cRec);
  for (this.i = 0; this.i < sarraylen(this.cRec); this.i++)
    this.poly[this.i] = strtofloat(#I(this.cRec,this.i));

  showpoly 300,this.poly;
  changeimgcolors 300,0,0,0,0;

  timeout = 0.05;
}

if (mousewheel){
  this.quality = max(2,min(20,this.quality+mousewheeldelta));
  setplayerprop #c,quality:#v(this.quality);
}

Well this was my approach, no corner npcs required. It’s just all subject to how you want to approach a problem really. Admittedly this approach is expensive and not really all that scale-able for a full 360 degrees. However, when applied to a segment like this flashlight example 2ndwolf implements, such an approach would appear quite feasible.

it looks like a snow angel

wow tricxta. looks like you got lazy at the end and left it looking shitty.

It was more a proof of concept than something I’d actually use and I’ve just used it here to showcase a point. That being, while the engine is dated, there are certain routes that can be taken to achieve difficult problems somewhat efficiently(not murdering someone’s cpu).

hey now! you just commended gs1! i knew it was great

too bad stefan didnt add an iswalking or hasmoved flag. that would have removed the need of a timeout loop.

Agreed, such things are only obvious once the engine has been used extensively by other people though, at the time of development such things are easy to miss. A new engine would really come into its own in that respect.

I mean, this code is cool and all, but it’s no greedy walker.

true that. greedy walker is the champion of gs1 scripts.

You mean the a star walker!

make the greedy walker detect the player with this script.