A chat system

This is for learning purposes, but feel free to use it. This is the same chat system as what evi uses.
Seeing as Twiggy has disappeared this code would just go to waste otherwise.

Notes:
-you can set a message for the player to receive when they log on by creating a server string called server.motd
-for example:server.motd=Welcome player, so nice of you to drop by!
-If a message is seen to contain ‘www’ it’ll underline the text and allow the player to click on the text to take them to that website.
-if (windowResized) will not work unless you’ve scripted your own support for it which I did for evi. You can easily setup your own using a timeout loop, comparing screenwidth and screenheight on each frame(or whatever interval you like) and using callweapon. Refer to commands.rtf to see how these functions & variables work.

Setting it up:
1)Add massmessage.txt to your execscripts directory, if you can’t see this. Add the following folder right to your player
RW execscripts/*

2)make sure your execscript triggerhacks are set to true in your serveroptions!

3)add the script to a npc in any level, the osl is an ideal place

4)Have fun

Commands:
/mass ‘text’
/help
/pm ‘target account’ ‘msg’
/clear

Also note, the message skin image was a rushed job taking no more than 5 minutes. Feel free to use it or make your own.

if (playerenters || timeout){
  if (!isweapon)toweapons -MessageNotify;
  timereverywhere;
  setstring this.img,tricxta_msg-skin.gif;//CHANGE THIS LINE IF YOU WANT TO USE YOUR OWN SKIN
  setstring this.charMap,"#,|#K(59)-{-}-;
  this.colours = {
    1,0.7,0.7,
    0,0,1,
    1,0,1,
    0.5,1,0,
    0,1,0,
    0.7,0.7,1,
    1,1,1
  };
  if (this.motd == 0){
    this.motd = 1;
    wraptext 65,,[MOTD] #s(server.motd);
    this.colour = 5;
    addMessage();
  }
  draw();
}
function draw(){
  this.placeX = screenwidth-332;
  this.placeY = screenheight - 92;
  this.scroll = max(0,min(this.idTrack-5,this.scroll));
  showimg 300,#s(this.img),this.placeX,this.placeY;
  changeimgpart 300,0,0,314,92;
  changeimgmode 300,1;
  changeimgcolors 300,1,1,1,0.5;
  showimg 301,#s(this.img),this.placeX+314,this.placeY;
  changeimgpart 301,314,0,18,18;
  showimg 302,#s(this.img),this.placeX+314,this.placeY+74;
  changeimgpart 302,314,74,18,18;

  this.scrollHeight = (this.idTrack>4)?max(10,(5/this.idTrack)*56):56;
  this.scrollDist = (this.idTrack>4)?(this.scroll/(this.idTrack-5))*(56-this.scrollHeight):0;
  showimg 303,#s(this.img),this.placeX+314,this.placeY+18+this.scrollDist;
  changeimgpart 303,314,18,18,this.scrollHeight-5;
  showimg 304,#s(this.img),this.placeX+314,this.placeY+18+this.scrollDist+this.scrollHeight-6;
  changeimgpart 304,314,68,18,6;

  for (this.i = 0; this.i < 5;this.i++){
    this.lineInd = this.scroll+this.i;
    if (this.lineInd >= this.idTrack)hideimg 305+this.i;
    else {
      setstring this.style,l;
      if (lindexof(#v(this.lineInd),this.linkLines) >= 0)setstring this.style,lu;
      showtext 305+this.i,this.placeX+10,this.placeY+5+this.i*15,arial,#s(this.style),#I(this.line#v(this.lineInd),0);
      this.cIndex = strtofloat(#I(this.line#v(this.lineInd),1));
      changeimgcolors 305+this.i,this.colours[this.cIndex*3],this.colours[this.cIndex*3+1],this.colours[this.cIndex*3+2],;
      changeimgzoom 305+this.i,0.5;
    }
  }
  for (this.i = 0; this.i < 10; this.i++){
    changeimgvis 300+this.i,(this.i<3)?4:5;
  }
}
if (windowResized){
  draw();
}
if (mousedown){
  if (mousescreenx in |this.placeX+314,this.placeX+314+19|){
    for (this.i = 0; this.i <2; this.i++){
      this.mY = this.placeY+this.i*70;
      if (mousescreeny in |this.mY,this.mY+21|){
        this.scroll += vecy(this.i*2);
        draw();
      }
    }
  }
  else if (mousescreenx in |this.placeX,this.placeX+314| && mousescreeny in |this.placeY,this.placeY+92|){
    this.line = this.scroll+int((mousescreeny-this.placeY)/15);
    if (lindexof(#v(this.line),this.linkLines) >= 0){
      tokenize #I(this.line#v(this.line),0);
      for (this.l = 0; this.l < tokenscount; this.l++){
        if (startswith(www,#t(this.l)))
          openurl #t(this.l);
      }
    }
  }
}
if (mousewheel){
  if (mousescreenx in |this.placeX,this.placeX+332| && mousescreeny in |this.placeY,this.placeY+92|){
    this.scroll += mousewheeldelta;
    draw();
  }
}
if (addMessage){
  wraptext 65,,#p(0);
  this.colour = strtofloat(#p(1));
  addMessage();
}
if (playerchats && isweapon){
  if (startswith(/mass,#c)){
    triggeraction 0,0,gr.es_clear,;
    setstring this.message,#e(6,strlen(#c),#c);
    if (strequals(#s(client.isAdmin),1))setstring this.title,Admin;
    else setstring this.title,Mass;

    prepMessage();

    setstring this.message,[#s(this.title) #a] #s(this.message);
    triggeraction 0,0,gr.es_set,#s(this.message);
    triggeraction 0,0,gr.es,ALLPLAYERS,MassMessage.txt;
    setplayerprop #c, ;
  }
  else if (startswith(/pm,#c)){
    tokenize #c;
    if (strequals(#t(1),#a))return;
    triggeraction 0,0,gr.es_clear,;
    setstring this.receiver,#t(1);
    setstring this.message,#e(5+strlen(#t(1)),strlen(#c),#c);

    wraptext 65,,[PM:#a->#s(this.receiver)] #s(this.message);
    this.colour = 0;
    addMessage();
    prepMessage();
    setstring this.message,[PM:#a->#s(this.receiver)] #s(this.message);
    triggeraction 0,0,gr.es_set,#s(this.message);
    triggeraction 0,0,gr.es,#s(this.receiver),MassMessage.txt;
    setplayerprop #c, ;
  }
  else if (strequals(#c,/help)){
    tokenize "[Help] Commands:",
      "/mass 'message' to send out a message to all",
      "/clear to clear this box","/toggle nicknames to hide/show names",
      "/changec x x x x x x where x is a number between 0 and 1",
      "/pm 'account' 'message'";
    this.colour = 5;
    addMessage();
    setplayerprop #c, ;
  }
  else if (strequals(#c,/clear)){
    for (this.i = 0; this.i < this.idTrack; this.i++)setstring this.line#v(this.i),;
    this.scroll = 0;
    this.idTrack = 0;
    hideimgs 305,310;
    setplayerprop #c, ;
    setstring this.linkLines, ;
    this.motd = 0;
    timeout = 0.05;
  }
}
function addMessage(){
  for (this.i = 0; this.i < tokenscount; this.i++){
    setstring this.line#v(this.idTrack),"#t(this.i)",#v(this.colour);
    if (strcontains(#t(this.i),www))
      addstring this.linkLines,#v(this.idTrack);
    this.idTrack++;
  }
  this.scroll = this.idTrack-5;
  draw();
}
function prepMessage(){
  setstring this.copy,#s(this.message);
  setstring this.message,;
  for (this.i = 0; this.i < strlen(#s(this.copy)); this.i++){
    setstring this.char,#e(this.i,1,#s(this.copy));
    for (this.c = 0; this.c<strlen(#s(this.charMap));this.c+=2){
      if (strequals(#s(this.char),#e(this.c,1,#s(this.charMap))))setstring this.char,#e(this.c+1,1,#s(this.charMap));
    }
    setstring this.message,#s(this.message)#s(this.char);
  }
}

Nice ! I try’ed it out pretty nifty :smiley: Is /mass | Like global chat?
OH MOTD Stays on the top when you chat it over laps it :stuck_out_tongue:

sure is