Author Topic: "Ready Made" Solutions - Scripts, tricks, tips, and other useful info.  (Read 14454 times)

Offline codave

  • Professional Noob Trainer
As suggested, this topic is for "Ready Made" works that people wish to share with the community, or other tips, tricks, and hints.

Also, check out these:
http://forum.newfmc.pl/index.php?board=11.0
http://fonline.ru/forum/forumdisplay.php?s=79df0d600c79ad37bf89288db19870f9&f=5

(English speakers, get a Translator extension for your browser.)

Awareness:

HP/HP, Injured  (With HP colorizing based on % of max HP)
Hand Slot Item/Unarmed
Armor/No Armor

Pretty close to 2238 Awareness, since I like the way it was implemented.  Some of the colors and percentages for HP may be off, but you can change them to suit your wants or needs.

First make a new script in the Server/Scripts folder, and name it "Awareness.fos".  Open it up, and paste in the following, and save it:
Code: [Select]
//Awareness On Mouse-Over
//Author: codave
#include "_macros.fos"
#include "_client_defines.fos"
#include "_colors.fos"
#include "_msgstr.fos"

void InitAwarenessHead() // Export
{

CritterCl@ cr = GetMonitorCritter(__MouseX, __MouseY); 
     if( !valid(cr) )
     return;
ItemCl@ item = cr.GetItem( 0, SLOT_HAND1 );
ItemCl@ itemArmor = cr.GetItem( 0, SLOT_ARMOR );
int hp_amo = cr.Stat[ ST_CURRENT_HP ];

if(valid(cr)  )
    {   
      int Y=__MouseY;
      int hp_proc = cr.Stat[ ST_CURRENT_HP ] * 100 / cr.Stat[ ST_MAX_LIFE ];   
        if(_CritIsInjured(cr))
       
         {
         if (hp_proc < 1)
         DrawText (cr.Stat[ST_CURRENT_HP]+"/"+cr.Stat[ST_MAX_LIFE]+", Injured", __MouseX, Y-60, 500, 100, COLOR_LGRAY, FONT_FALLOUT, FT_BORDERED);
         else if (hp_proc < 25)
         DrawText (cr.Stat[ST_CURRENT_HP]+"/"+cr.Stat[ST_MAX_LIFE]+", Injured", __MouseX, Y-60, 500, 100, COLOR_RED, FONT_FALLOUT, FT_BORDERED);
         else if (hp_proc < 50)
         DrawText (cr.Stat[ST_CURRENT_HP]+"/"+cr.Stat[ST_MAX_LIFE]+", Injured", __MouseX, Y-60, 500, 100, COLOR_DRED, FONT_FALLOUT, FT_BORDERED);
         else if (hp_proc <= 75)
         DrawText (cr.Stat[ST_CURRENT_HP]+"/"+cr.Stat[ST_MAX_LIFE]+", Injured", __MouseX, Y-60, 500, 100, COLOR_DGREEN, FONT_FALLOUT, FT_BORDERED);         
         else if (hp_proc <= 100)
         DrawText (cr.Stat[ST_CURRENT_HP]+"/"+cr.Stat[ST_MAX_LIFE]+", Injured", __MouseX, Y-60, 500, 100, 0x0, FONT_FALLOUT, FT_BORDERED);
          Y=Y+13; 
          }
         
      else
     
          {
         if (hp_proc < 1)
         DrawText (cr.Stat[ST_CURRENT_HP]+"/"+cr.Stat[ST_MAX_LIFE], __MouseX, Y-60, 500, 100, COLOR_LGRAY, FONT_FALLOUT, FT_BORDERED);
         else if (hp_proc < 25)
         DrawText (cr.Stat[ST_CURRENT_HP]+"/"+cr.Stat[ST_MAX_LIFE], __MouseX, Y-60, 500, 100, COLOR_RED, FONT_FALLOUT, FT_BORDERED);
         else if (hp_proc < 50)
         DrawText (cr.Stat[ST_CURRENT_HP]+"/"+cr.Stat[ST_MAX_LIFE], __MouseX, Y-60, 500, 100, COLOR_DRED, FONT_FALLOUT, FT_BORDERED);
         else if (hp_proc <= 75)
         DrawText (cr.Stat[ST_CURRENT_HP]+"/"+cr.Stat[ST_MAX_LIFE], __MouseX, Y-60, 500, 100, COLOR_DGREEN, FONT_FALLOUT, FT_BORDERED);
         else if (hp_proc <= 100)
         DrawText (cr.Stat[ST_CURRENT_HP]+"/"+cr.Stat[ST_MAX_LIFE], __MouseX, Y-60, 500, 100, 0x0, FONT_FALLOUT, FT_BORDERED);
          Y=Y+13; 
          }
         
      if(valid(itemArmor)) 
            { 
            DrawText (""+GetMsgStr(TEXTMSG_ITEM, STR_ITEM_INFO(itemArmor)), __MouseX, Y-60, 500, 100, 0x0, FONT_FALLOUT, FT_BORDERED); 
            Y=Y+13;
            }
         
      else
     
         {
         DrawText ("No Armor", __MouseX, Y-60, 500, 100, COLOR_LGRAY, FONT_FALLOUT, FT_BORDERED);
         Y=Y+13;
            } 
         
      if(valid(item)) 
            { 
            DrawText (""+GetMsgStr(TEXTMSG_ITEM, STR_ITEM_INFO(item)), __MouseX, Y-60, 500, 100, 0x0, FONT_FALLOUT, FT_BORDERED);
            }
         
         else
       
         {
         DrawText ("Unarmed", __MouseX, Y-60, 500, 100, COLOR_LGRAY, FONT_FALLOUT, FT_BORDERED);
            }
         
   } 
   




Next, find "client_main.fos".  We need to include the Awareness script we just created.  In the headspace, enter "#include "awareness.fos", so it looks like this:
Code: [Select]
#include "_client_defines.fos"
#include "_macros.fos"
#include "_msgstr.fos"
#include "sprite.fos"
#include "_colors.fos"
#include "_animation.fos"
#include "awareness.fos"

Scroll down a bit further and find "GUI_Init();", and enter in "InitAwarenessHead();" so it looks like this:
Code: [Select]
GUI_Init();
    InitNameColorizing();
    InitIgnoreList();
    // InitTestScreen();
    InitRadioScreen();
    InitChosenTabs();
   InitAwarenessHead();
    #ifdef PLAYERS_3D
    Init3DChaRegScreen();
    #endif

Scroll down a little further and find "Void render_iface( unit layer)".  Paste in the following, so it looks like this:
Code: [Select]
void render_iface( uint layer )
{

      if(layer == 1 )
   {
   CritterCl@ chosen = GetChosen(); 
        if(valid(chosen) && chosen.Perk[PE_AWARENESS] != 0) 
      {
      InitAwarenessHead();
      }
   }

    if( layer == 3 )
    {
        DrawChosenTabs();
        GUI_Render();
    }

The color codes can be found in _colors.fos, if you want to change them. 

A big thanks to lothar70 and Wipe for some help with this.
« Last Edit: January 30, 2013, 02:16:09 pm by codave »

Offline Ganado

  • Moderator
  • Dishonest Abe
Thank you for this. :)
Error while opening cfg file: spawnnpc.cfg
Shit! Damn admins! Always ruining my fun! I guess I'll talk to them. WITH MY FISTS!!!! No seriously, I will write them a nice email or make a thread on the forums or something. Thanks!


Offline Wipe

  • Rotator
  • Random is god
My first guess was that using 4x DrawText() in a row instead of one (cos "\n" [new line] actually works in there) may cause slowdowns - DrawText() isn't "cheap" function, as we all know. But after closer look:

Code: [Select]
CritterCl@ cr = GetMonitorCritter(__MouseX, __MouseY); 
ItemCl@ item = cr.GetItem( 0, SLOT_HAND1 );
ItemCl@ itemArmor = cr.GetItem( 0, SLOT_ARMOR );
int hp_amo = cr.Stat[ ST_CURRENT_HP ];

I really advice to put something like this after 1st line
Code: [Select]
if( !valid(cr) ) return;
Without it, client tries to get cr Items at the current mouse xy - problem is that cr can be null, and yet you are trying to get info from it - without checking if you actually have a Critter pointer. If you don't, 2nd+ lines creates an error, which client tries to log into file (and as you fiddle with scripts, i guess that you have logging to FOnline.log enabled) on every frame render~ That's no good, everything what's called inside render_iface() function should be guarded with sanity checks, like any other (reserved) functions which are called by client frequently.

--- I hope you get what i mean, i suck in explaining things...
« Last Edit: July 30, 2012, 10:26:58 pm by Wipe »
Games are meant to be created, not played...

Offline codave

  • Professional Noob Trainer
I understand completely.  Thank you, that cleared the problem right up.  It's now smooth as hell.

 ;D

I need to get better at this scripting thing.
« Last Edit: August 02, 2012, 01:04:14 am by codave »

Offline Berko

  • Tim Tom Ted
    • http://kabefis.deviantart.com/
Re: "Ready Made" Solutions - Scripts, tricks, tips, and other useful info.
« Reply #5 on: August 01, 2012, 05:06:36 pm »
For "OnHead" information you can do something like that :
this only add information on head and nothing more so it need modification to be used like awareness if you use it, etc
maybe it can be optimized (like change something only when needed)
comment is here to help with this example

The script file, i named it "gui_client_onhead.fos"
Code: [Select]
#include "_defines.fos"
#include "_client_defines.fos"
#include "_colors.fos"
import int GUI_GetActiveMainScreen() from "client_gui";


#define GUI_ONHEAD_NB_MOD 4 //Number of mod that we can switch

#define GUI_ONHEAD_EMPTY 0 //Show nothing
#define GUI_ONHEAD_NAME 1 //Show the name
#define GUI_ONHEAD_DETAILS 2 //Show the name and HP
#define GUI_ONHEAD_DEBUG 3 //Show the name, id and pid


//global variable to store the current mod
uint GUI_OnHead_Mod;


//Initialize all that we need to initialize
void Init_GUI_OnHead()
{
GUI_OnHead_Mod = GUI_ONHEAD_EMPTY;
}


//Draw function where we change informations on head
void Draw_GUI_OnHead()
{

if( GUI_GetActiveMainScreen() != CLIENT_MAIN_SCREEN_GAME )
        return;

CritterCl@ cr = GetChosen();
CritterCl@[] crs;
GetCritters( 0, FIND_ALL, crs );

switch(GUI_OnHead_Mod)
{
case GUI_ONHEAD_EMPTY:
for(uint  i = 0, imax = crs.length(); i < imax; i ++)
{
crs[i].NameOnHead = "";
}
__ShowPlayerNames = false;

break;

case GUI_ONHEAD_NAME:
for(uint  i = 0, imax = crs.length(); i < imax; i ++)
{
crs[i].NameOnHead = "";
}
__ShowPlayerNames = true;

break;

case GUI_ONHEAD_DETAILS:
{
int color_b = 0;
int color_g = 0;
int color_r = 0;
for(uint  i = 0, imax = crs.length(); i < imax; i ++)
{
color_g = (255*crs[i].Param[ST_CURRENT_HP])/crs[i].Param[ST_MAX_LIFE];
if(color_g < 0)
color_g = 0;
color_r = 255 - color_g;
crs[i].NameOnHead = crs[i].Name + "\n|" + COLOR_RGB(color_r, color_g, color_b) + " " + crs[i].Param[ST_CURRENT_HP] + "/" + crs[i].Param[ST_MAX_LIFE];
}
__ShowPlayerNames = true;

break;
}

case GUI_ONHEAD_DEBUG:
for(uint  i = 0, imax = crs.length(); i < imax; i ++)
{
crs[i].NameOnHead = crs[i].Name + "\n|" + COLOR_CONTOUR_YELLOW + " Id : " + crs[i].Id + "\nPid : " + crs[i].Pid;
}
__ShowPlayerNames = true;

break;

default :
GUI_OnHead_Mod = GUI_ONHEAD_EMPTY;

break;
}
}


//Called when we push F6
void Change_GUI_OnHead()
{
GUI_OnHead_Mod = (GUI_OnHead_Mod + 1) % GUI_ONHEAD_NB_MOD;
}

//Called when we push F7
void ShowNPC_GUI_OnHead()
{
__ShowNpcNames =  !__ShowNpcNames;
}


Add the module in script.cfg

In client_main.fos import functions
Code: [Select]
import void Init_GUI_OnHead() from "client_gui_onhead";
import void Draw_GUI_OnHead() from "client_gui_onhead";
import void Change_GUI_OnHead() from "client_gui_onhead";
import void ShowNPC_GUI_OnHead() from "client_gui_onhead";

and call these function where they need to be called
Code: [Select]
...

bool start()
{
    ...
    Init_GUI_OnHead();
    ...
}

...

void render_iface( uint layer )
{
    ...
    if( layer == 3 )
    {
        ...
        Draw_GUI_OnHead();
        ...
    }
    ...
}

...

bool key_down( uint8 key )
{
...
if(key == DIK_F6)
{
Change_GUI_OnHead();
return true;
}
if(key == DIK_F7)
{
ShowNPC_GUI_OnHead();
return true;
}
...
}

...

When you push F6 it change the mode of informations on head. F7 only show or not the same informations for NPC. "Details" mode shows HP information only with gradient color from red to green. When it show additional information, the name keep the original color (color set in namecolorizing or NameColor).

Sorry for my English and I hope this example can be useful.
~~~ Ashes of Phoenix project --> http://fonline-aop.net/ ~~~

Offline codave

  • Professional Noob Trainer
Re: "Ready Made" Solutions - Scripts, tricks, tips, and other useful info.
« Reply #6 on: August 12, 2012, 03:05:28 am »
GUI Timeouts:

One of the many familiar features that the SDK is missing, and is great to have.

First, make a new script and name it "timeouts.fos", and paste in the following:

Code: [Select]
//On-Screen Timeouts
//By: codave
#include "_macros.fos"
#include "_client_defines.fos"
#include "_colors.fos"
#include "_msgstr.fos"
#include "_defines.fos"

import int GUI_GetActiveMainScreen() from "client_gui";
import int GUI_GetActiveScreen() from "client_gui";

void InitTimeouts()
{
if( GUI_GetActiveMainScreen() != CLIENT_MAIN_SCREEN_GAME )
        return;

    CritterCl@ chosen = GetChosen();
    if( not valid( chosen ) )
        return;
int Y=30;
int X=10;

if( chosen.Timeout[ TO_SK_LOCKPICK ] > 0 )
{
        DrawText("Lockpick: "+chosen.Timeout[ TO_SK_LOCKPICK ] / 10, X, Y-0, 500, 100, COLOR_GREEN, FONT_FALLOUT, FT_BORDERED );
Y=Y+15;
}

if( chosen.Timeout[ TO_SK_FIRST_AID ] > 0 )
{
        DrawText("First Aid: "+chosen.Timeout[ TO_SK_FIRST_AID ] / 10, X, Y-0, 500, 100, COLOR_GREEN, FONT_FALLOUT, FT_BORDERED );
Y=Y+15;
}

if( chosen.Timeout[ TO_SK_DOCTOR ] > 0 )
{
        DrawText("Doctor: "+chosen.Timeout[ TO_SK_DOCTOR ] / 10, X, Y-0, 500, 100, COLOR_GREEN, FONT_FALLOUT, FT_BORDERED );
Y=Y+15;
}

if( chosen.Timeout[ TO_SK_REPAIR ] > 0 )
{
        DrawText("Repair: "+chosen.Timeout[ TO_SK_REPAIR ] / 10, X, Y-0, 500, 100, COLOR_GREEN, FONT_FALLOUT, FT_BORDERED );
Y=Y+15;
}

if( chosen.Timeout[ TO_BATTLE ] > 0 && chosen.Timeout[ TO_BATTLE ] < 10000 )
{
        DrawText("Battle: "+chosen.Timeout[ TO_BATTLE ] / 10, X, Y-0, 500, 100, COLOR_GREEN, FONT_FALLOUT, FT_BORDERED );
Y=Y+15;
}

if( chosen.Timeout[ TO_REPLICATION ] > 0 )
{
        DrawText("Respawn Time: "+chosen.Timeout[ TO_REPLICATION ] / 10, X, Y-0, 500, 100, COLOR_GREEN, FONT_FALLOUT, FT_BORDERED );
Y=Y+15;
}

if( chosen.Timeout[ TO_SK_STEAL ] > 0 )
{
        DrawText("Steal: "+chosen.Timeout[ TO_SK_STEAL ] / 10, X, Y-0, 500, 100, COLOR_GREEN, FONT_FALLOUT, FT_BORDERED );
Y=Y+15;
}
}

Save it in the /server/scripts folder.

Next, open up client_main.fos, and add the script we just saved to the namespace at the top, like so:
Code: [Select]
// Author: cvet, Atom
// Client main script
// Compile using fo_client.dll
#include "_client_defines.fos"
#include "_macros.fos"
#include "_msgstr.fos"
#include "sprite.fos"
#include "_colors.fos"
#include "_animation.fos"
#include "awareness.fos"
#include "timeouts.fos"

Go down a bit further into the script, and find GUI_Init();, and add "InitTimeouts();, like this:
Code: [Select]
GUI_Init();
    InitNameColorizing();
    InitIgnoreList();
    // InitTestScreen();
    InitRadioScreen();
    InitChosenTabs();
    InitAwarenessHead();
    InitTimeouts();
    #ifdef PLAYERS_3D
    Init3DChaRegScreen();
    #endif

Scroll down further, and find "void render_iface", and add the same Init.
Code: [Select]
if( layer == 3 )
    {
InitTimeouts();
        DrawChosenTabs();
        GUI_Render();
    }

After everything is saved, fire the server up and test it.  You can easily make color/x, y, and order adjustments on the fly by clicking "Reload Client Scripts" on the Server, and your changes will show up in game after a few seconds.

Enjoy...
« Last Edit: August 12, 2012, 03:08:07 am by codave »

Offline Gob

  • The Good
Re: "Ready Made" Solutions - Scripts, tricks, tips, and other useful info.
« Reply #7 on: August 26, 2012, 05:57:31 pm »
After using Berko's code I'm getting this:

Code: [Select]
Script::BindImportedFunctions - Fail to bind imported functions, module<client_main>, error<-19>.
I know it has something to do with the imports :/ but what?

Offline SEGA_RUS

  • Arbeit macht frei
Re: "Ready Made" Solutions - Scripts, tricks, tips, and other useful info.
« Reply #8 on: September 05, 2012, 02:39:04 pm »
Code: [Select]
Script::BindImportedFunctions - Fail to bind imported functions, module<client_main>, error<-19>.I know it has something to do with the imports :/ but what?
it means, that something does wrong when server trying to execute one of important function from awareness.fos or/and timeouts.fos before compiling

Code: [Select]
#include "awareness.fos"
#include "timeouts.fos"
check did u put this code in client_main
check did u added script name(s) to scripts.cfg
check did u copy all 2 files with right filenames ;D ;D
Skype - sega_75rus

Re: "Ready Made" Solutions - Scripts, tricks, tips, and other useful info.
« Reply #9 on: August 17, 2016, 01:55:51 pm »
I followed above Codave's Awareness tutorial but something went wrong, it is how looks error during server start:

Code: [Select]
[29:433] Script system initialization complete.
[29:539] Loading language packs...
[32:205] Loading language packs complete, loaded<2> packs.
[32:252] Reload client scripts...
[35:691] Script message: client_main : Error : Unexpected end of file : 14975, 1.
[35:769] Script message: client_main : Info : While parsing statement block : 12706, 1.
[35:857] Script::LoadScript - Unable to Build module<client_main>, result<-1>.
[35:910] FOServer::ReloadClientScripts - Unable to load client script<client_main>.
[38:278] Reload client scripts complete.
[38:417] AI manager initialization...
[38:510] Find bags...
[38:797] Loaded<156> bags.
[38:844] AI manager initialization complete.

Some conclusions?
I had similiar problem with adding GUI Timeouts. Looks like Im making same fault in some step.
(Im using tla sdk not 2238)
« Last Edit: August 17, 2016, 03:37:16 pm by Moe Lester »

Re: "Ready Made" Solutions - Scripts, tricks, tips, and other useful info.
« Reply #10 on: August 18, 2016, 08:50:01 pm »
Quote
[35:691] Script message: client_main : Error : Unexpected end of file : 14975, 1.
[35:769] Script message: client_main : Info : While parsing statement block : 12706, 1.

New to FOnline and AngelScript but based on my general knowledge of coding errors I would hazard a guess that you messed up the formatting on line 12706 and an unresolved bit of code is causing the parser to freak out at the end of the file at line 14975.

Check where you inserted this code:

Code: [Select]
...

bool start()
{
    ...
    Init_GUI_OnHead();
    ...
}

...

void render_iface( uint layer )
{
    ...
    if( layer == 3 )
    {
        ...
        Draw_GUI_OnHead();
        ...
    }
    ...
}

...

bool key_down( uint8 key )
{
...
if(key == DIK_F6)
{
Change_GUI_OnHead();
return true;
}
if(key == DIK_F7)
{
ShowNPC_GUI_OnHead();
return true;
}
...
}

...

Make sure all brackets and parens are in proper pairs and nothing is left unclosed.

Re: "Ready Made" Solutions - Scripts, tricks, tips, and other useful info.
« Reply #11 on: August 20, 2016, 09:38:17 pm »
Thanks mate! Yeah, I maked some minor faults, but your post motivated me to check out this crap again and again and at end I fixed my faults, also I experimented with this code and found working solution.
 


Now awareness and timeouts working for me without problems :)

Re: "Ready Made" Solutions - Scripts, tricks, tips, and other useful info.
« Reply #12 on: August 20, 2016, 09:39:50 pm »
Good to know my general experience works in FOnline. :) Happy to help.