The Dink Network

Help me Revise the DinkC reference.

July 29th 2021, 08:39 PM
custom_robj.png
Robj
Jester He/Him Australia
You feed the madness, and it feeds on you. 

EDIT: I'm not gonna make anymore posts on what changes I'm making or update any posts I've made, it's too tedius and doesn't yield any responses anyway. Once the full version is out, if anyone finds anything extra they think should be changed, they can contact me and I will make the changes, if I test them and deem them accurate.

I have started a thorough revision of the DinkC reference.

I've started making corrections now. As I correct things, or make additions to anything I'm going to drop it in this thread. I'll probably just update this first post, but bump it with a double, or triple post every now and then (I don't want it to fall to far below, and in fact I think this should be stickied until the revision is released?)

This is happening, and thanks to Kyles help, when we are done, it will be easily accessible by anyone with an internet connection, viewable directly from a web browser.

This might be the final thorough revision of the DinkC reference, so if you can think of anything, please let me know.

The plan is to correct all false information (there is a lot of it), and also to explain the differences in behaviour of certain functions between Dink Smallwood 1.08 and FreeDink. For now I'm not going to go into Dink Smallwood HD, since it has it's own limits in regards to variables, sequence slots, set_sprite_info lines, some new functions and also has compatiblity issues. I think if anything, it needs it's own separate Documentation in addition to the DinkC Reference. I think most of us can agree at this point that FreeDink seems to be the most widely used Engine for Dmodding, so that is why I will be including it in this DinkC Reference Revision.

Cheers.
July 29th 2021, 09:52 PM
peasantmb.gif
yeoldetoast
Peasant They/Them Australia
LOOK UPON MY DEFORMED FACE! 
There's a lot in the existing reference which is false for even 1.08. To start off with, (edited thanks) disable_all_sprites() doesn't actually work as intended at all. The pace of threads is so slow at the moment that stickying wouldn't change anything (skorn don't bump a whole ton of old ones).
July 29th 2021, 09:55 PM
custom_robj.png
Robj
Jester He/Him Australia
You feed the madness, and it feeds on you. 
Hi Toast. Do you mean "disable_all_sprites()"?

If so, I will note that down.
July 30th 2021, 12:16 AM
peasantmp.gif
Skurn
Peasant He/Him Equatorial Guinea duck bloop
can't flim flam the glim glam 
got it. which ones do you want me to necro?

*sharpens scythe*
July 30th 2021, 02:04 AM
peasantmb.gif
yeoldetoast
Peasant They/Them Australia
LOOK UPON MY DEFORMED FACE! 
Threads about DinkC commands not working as they are described in dinkc.chm
July 30th 2021, 03:48 AM
duck.gif
toof
Peasant He/Him
I disagree. 
Probably will never finish it. Maybe it helps, maybe it doesn't. Feel free to ask questions.
Here

Edit
If you're doing web version, maybe some tools like Notion can help...
July 31st 2021, 06:57 AM
custom_robj.png
Robj
Jester He/Him Australia
You feed the madness, and it feeds on you. 
Thanks Toof, I'll take a look.
August 4th 2021, 10:50 PM
custom_robj.png
Robj
Jester He/Him Australia
You feed the madness, and it feeds on you. 
Made some progress on the revision. The breakdown of what I changed (and what I changed it from), or added, is below.

Basing the revision off the DinkC Reference version 4.0, which is the latest, disregarding the physical hard copy book, which is basically a fancy version with images and stuff. I have a copy so am using it to check any differences/extra info that might be missing/incorrect as well.
For text I added that pertains to a specific Engine version, there will be a coloured tag with text in the final version that makes it obvious at a glance. In this thread I'll just be writing what version the additions/changes apply to.

**Changes So Far**

Chapter: What is DinkC?
Addition: Warning message
Applies to: FreeDink 109.6 only
Note that when DEBUG is active the DEBUG.TXT file will quickly grow in size and become bloated by several "Surface doesn't have a colorkey" reports.

===============================================
===============================================

Chapter: Scripts
Addition: Comment character limits.
In Dink Smallwood 1.08 comments have a character limit of 199(including the slashes). Any comments that exceed this limit can cause the game to crash.
This limit does not apply in certain specific circumstances and does not apply in Freedink. For best compatibility, avoid using comments that exceed 199 characters.


Change: Instructions on showing hidden file types. Old instructions were accurate to windows XP and older. New instructions accurate to ALL windows versions.
1. Locate the windows search box (on the task bar or in the start menu)
2. Search for 'Folder Options'
3. Select 'Folder Options' or 'File Explorer Options' (whichever is in your search list)
4. Select the 'View' tab
5. Uncheck the 'Hide extensions for known file types' checkbox.


Addition: Information given on when 'main.c' and 'start.c' are run. Added/changed to:
Main: When the game first starts up or `restart_game()` is called.
Start: When the game first starts up or `restart_game()` is called. After Main.c

===============================================
===============================================

Chapter: Variables
Change: Incorrect limit of local and gloabl variables that can be active at any given time.
FROM 248 TO 249

Change: Incorrect range of 'script number'.
FROM 1-299 TO 1-199

Change: Incorrect range of 'Active sprite number'.
FROM 1-300 TO 1-299

Change: Incorrect range of 'Soundbank Number'.
FROM 1-19 TO 1-20

===============================================
===============================================

Chapter: Procedures
Addition: Notes on changed behaviour and bugs pertaining to custom procedures in 1.08 and FreeDink.
Custom procedures called both externally and from within the same script will run on their own script number. Called procedures will not have access to previously declared local variables.

Calling custom procedures can randomly cause the calling script to continue past `}` and into code afterwards. In some cases it may even continue past a `return;`. A solution to this is using `goto` at the end of the calling procedure, and jump to the end of the script. Check out Jumps. (Jumps is a link that goes to the "Jumps" chapter, explaining 'goto')

Addition: Warning message of broken global procedures.
Note: Global Procedures are Bugged in Dink Smallwood 1.08 and Freedink. You can declare one Global Procedure and it will work fine, but declaring anymore will make none of them work(including the first one), and might cause the game to crash in some instances.

===============================================
===============================================

Chapter: Combat
Change/Addition: Changed the example of what the Dink engine's damage calculation might look in DinkC. Old example was correct for missiles, but wrong for physical hits. Here's the entire new section of step 1(damage calculation), revised and corrected:

Step 1. When Dink or a monster hits the other, a number of hitpoints is randomly selected from the upper half of its strength range. In DinkC terms, you might write it like this:

int &hit_work = sp_strength(<hitting-sprite> , -1);
int &hits = math_mod(&hit_work, 2);
&hit_work / 2;
int &add_remainder = &hit_work;
&add_remainder += &hits;
&hits = random( &add_remainder , &hit_work );
&hits += 1;


While the above example is true for melee combat, the damage calculation works slightly different for missiles.
When the missile's strength is an *odd* value, it's maximum possible damage potential will be one less than it's strength. In DinkC terms, it would look like this:

int &hit_work = sp_strength(<hitting-sprite>, -1);
&hit_work / 2;
int &hits = random(&hit_work, &hit_work);
&hits += 1;

===============================================
===============================================
August 4th 2021, 11:05 PM
custom_robj.png
Robj
Jester He/Him Australia
You feed the madness, and it feeds on you. 
====================
**FUNCTIONS (A - C)**
====================

Below is all the current changes/additions I've made to functions. I'm going through them from A - Z in order and will be posting what I add/change as I go. If a fucntion isn't listed, it didn't need changing.

Function: busy()
Addition: Added an example of one useful purpose of this function (maybe the only useful purpose):
One useful purpose of this function is to check if a sprite is currently saying something when it dies, and if so, kill off the text sprite. This will prevent the bug of the text sprite surviving, and instantly jumping to a different position on the screen.

void die(void)
{
 //if this sprite is saying anything, kill the text sprite
 int &gettext = busy(¤t_sprite);
 if (&gettext > 0)
 {
  sp_active(&gettext, 0);
 }
}


====================
**FUNCTIONS (D - G)**
====================

Function: disable_all_sprites()
Changed: Rewritten and example of how to actually disable all sprites.

`disable_all_sprites()` is supposed to disable all sprites on the current screen but does not work as intended. If this function worked as intended, the equivalent would be setting sp_disabled() to 1 for all sprites.

This functions will disable several sprites, but will leave at least 1 enabled, sometimes more.

Here is a nice work around that will accomplish the true intention of this command, and will disable all sprites instantly.


 //there can be a maximum of 299 actve sprite numbers
 //we'll start at 2 to exlude Dink.
 //If you want to disable Dink as well, change the following line to 'int &getsp = 1;'
 int &getsp = 2;
 int &sprite_exist;
loop:
 //check if a sprite exists with this active sprite number
 &sprite_exist = sp_active(&getsp, -1);
 if (&sprite_exist > 0)
 {
  //this sprite exists - so disable it.
  sp_disabled(&getsp, 1);
 }
 if (&getsp < 299)
 {
  //increment active sprite number '&getsp' and loop.
  &getsp += 1;
  goto loop;
 }


===============================================
===============================================

Function: disable_all_sprites()
Changed: Rewritten and example of how to actually enable all sprites.

`enable_all_sprites()` is supposed to enables all sprites after they have been disabled with disable_all_sprites() or sp_diabled(). This function does not work as intended.

Here is a nice work around that will accomplish the true intention of this command, and will enable all sprites instantly.


 //there can be a maximum of 299 actve sprite numbers
 //check every active sprite number for active sprites and enable them all
 int &getsp = 1;
 int &sprite_exist;
loop:
 //check if a sprite exists with this active sprite number
 &sprite_exist = sp_active(&getsp, -1);
 if (&sprite_exist > 0)
 {
  //this sprite exists - so enable it.
  sp_disabled(&getsp, 0);
 }
 if (&getsp < 299)
 {
  //increment active sprite number '&getsp' and loop.
  &getsp += 1;
  goto loop;
 }


===============================================
===============================================

Function: external()
Addition: Added warning for external bug

Calling a procedure with `external()` can randomly cause the calling script to continue past `}` and into code afterwards. In some cases it may even continue past a `return;`. A solution to this is using `goto` at the end of the calling procedure, and jump to the end of the script.`

===============================================
===============================================

Function: fade_up()
Addition: FreeDink bug of text not visible, and workaround explanation.
[FreeDink, all versions] when the game is in fullscreen mode, or the window is resized in window mode, text will be barely visible. A work around for this is to warp Dink to a screen with no sprites, filled with black tiles, and make Dink invisible using `sp_nodraw()`. Then do `fade_up()` and create your text.

===============================================
===============================================

Function: get_version()
Addition: Note that FreeDink engine version can be returned through Dinkc, and a link to Version Checker.
[i]Note: FreeDink Engine versions are not returned using this function, it will only return `108` (Or `107` if running in 1.07 mode). If you need to get the FreeDink engine version, this can be accomplished through DinkC, check out: Version Checker.
August 15th 2021, 02:53 AM
custom_robj.png
Robj
Jester He/Him Australia
You feed the madness, and it feeds on you. 
I had to bump, because when I tried to add all this to the above post, it says it's too much content. So, some of it is added above, some in this bump.

====================
**FUNCTIONS (H - K)**
====================

Function: hurt()
Addition: Made a few different additions. Below is the entire revised function doc.
hurt() damages active_sprite with damage amount of damage. Note that it will damage an exact amount, but it does take defense into account. Also, there is still a chance of 1 damage if the defense of active_sprite is higher than int damage.

This function will always trigger the hit() procedure of active_sprite (even if no damage is dealt).

If the active_sprite receives damage, blood spurts are added, free of charge.


[Dink version < 1.08]:
- A negative damage value would cause the game to freeze.
- If the script that calls this function is attached to a sprite, Required global variable `&enemy_sprite` will be updated to `¤t_sprite`.


[Dink version 1.08, FreeDink all versions]:
- Ignores the command safely.
- If the script that calls this function is attached to a sprite, Required global variables `&enemy_sprite` and `&missle_source` will be updated to `¤t_sprite`.


===============================================
===============================================

Function: init()
Addition: Made a few different additions. Below is the entire revised function doc.

init() allows you to execute a line normally run from the dink.ini file. It can be used to replace graphics on the fly, such as for Dink's weapons, or anything else.

// excerpt from item-sw1.c
init("load_sequence_now graphics\dink\sword\walk\d-sw1- 71 43 64 69 -14 -10 14 10");
init("load_sequence_now graphics\dink\sword\walk\d-sw2- 72 43 35 70 -21 -10 19 10");
init("load_sequence_now graphics\dink\sword\walk\d-sw3- 73 43 28 69 -13 -9 13 9");
init("load_sequence_now graphics\dink\sword\walk\d-sw4- 74 43 66 75 -14 -12 20 12");

If replacing sequences with different numbers of frames, the longest sequence should be loaded first in the dink.ini, otherwise it might replace frames in other sequences.

[Dink version < 1.08]:
init() only works well if the graphics are in dir.ff format. If the graphics are plain bmps, and the replaced sequence is played, it may include frames from other sequences.


[Dink version 1.08, FreeDink all versions]:
init() will work well with plain bmps, there is no need to pack the graphics into dir.ff format.


===============================================
===============================================

Function: initfont()
Addition: Made a few different additions. Below is the entire revised function doc.

initfont() will cause the game to use font for all current and future text. Note that the font must be installed as a normal font (in the Windows/Fonts folder on Windows). The default font is 'Arial'.

There are some differences in the way font is interpreted between Dink/Freedink, and also between font filetypes.

Depending on the Dink Engine version and the font filetype, you will need to specify font as either a font name, or the actual font filename.

TIP

The Font Name is the name displayed when you preview a font by opening it.

The actual font filename is viewed in the file properites - Right Click on the font and click properties and find the filename.

Below you will find the requirements for string font based on filetype and Dink Engine version.

[FreeDink, all versions]: Only Truetype fonts(*.ttf) are compatible with initfont()


*.ttf: [Dink, all versions]: Font name.
[Freedink, all versions]: File name.

*.fon, *.ttc: [Dink, all versions]: Font name.

*.otf: [Dink, all verisons]: File name.

===============================================
===============================================

Function: kill_cur_item()
Addition: Added warning of flaw in function and a workaround example.

WARNING

The game will stop executing the script once this function is called. The item will be killed, but the item image will remain in the status bar until draw_status() is called.

Be careful not to call kill_cur_item from a spawned script, or it will stop executing and survive forever.

Here is a nice work around to fix the flaw in this function, using set_callback_random() to callback a procedure in the script, after it stops executing:

void main(void)
{
 //set a callback to the 'killscript()' proc, with a wait time of 1.
 //so after we run the flawed 'kill_cur_item()' function, it immediately runs 'killscript()'
 set_callback_random("killscript", 1, 1);

 //flawed 'kill_cur_item()' function - will stop the current script executing
 kill_cur_item();
}

void killscript(void)
{
 //this will run immediately after 'kill_cur_item()'
 //draw the status to make the item image vanish properly
 draw_status();

 //kill off this script so it doesn't remain in memory.
 kill_this_task();
}


===============================================
===============================================

Function: kill_cur_magic()
Addition: Similar additions to kill_cur_item, but changed to suit kill_cur_magic. See above.

===============================================
===============================================

Function: kill_this_magic()
Addition: Added warning of flaw in function and a workaround example.

WARNING

If the magic being killed off is currently armed when this function is called, the item image in the status bar will also vanish, and the green magic charge bar can sometimes be left behind.

Here is a work around to fix the flaw in this function:

void main(void)
{
 //store '&cur_weapon' in a local variable
 int &fix_weap = &cur_weapon;

 //kill off the fireball spell
 kill_this_magic("item-fb");

 //fix unwanted side effects with magic charge bar and empty slot staying equipped
 &cur_magic = 0;
 &magic_cost = 0;
 &magic_level = 0
 arm_magic();

 //restore &cur_weapon, arm it, and draw the status
 &cur_weapon = &fix_weap;
 arm_weapon();
 draw_status();
}
August 27th 2021, 11:22 AM
spike.gif
SlipDink
Peasant He/Him United States bloop rumble
2nd generation. No easy way to be free. 
Robj:
Are you aware of any solutions to the apparent problem of neither draw_hard_sprite(int active_sprite) nor draw_hard_map() causing a change in hardness on a particular sprite that you have used sp_hard(int active_sprite, 1) on?

It seems to me that sometimes a sprite that I want to make disappear using sp_nodraw(int active_sprite, 1) and then have no hardness using sp_nodraw(int active_sprite, 1) on will not loose it's hardness, no matter what I do. But, if Dink leaves the screen and comes back, then the hardness change has taken place.

Is this an occasional problem for others or am I just doing something wrong?
August 27th 2021, 03:02 PM
custom_robj.png
Robj
Jester He/Him Australia
You feed the madness, and it feeds on you. 
"Robj:
Are you aware of any solutions to the apparent problem of neither draw_hard_sprite(int active_sprite) nor draw_hard_map() causing a change in hardness on a particular sprite that you have used sp_hard(int active_sprite, 1) on?


Can you send me a sample script?

Draw_hard_map should always work, can't say I've encountered that issue.
If you're using draw_hard_sprite, this just updates the sprites hardness in it's current location, based on it's sp_hard value. So if you move a hard sprite, then use draw_hard_sprite() to make it not hard, the old hardness would still remain in the position before it moved. But it doesn't sound like that's the issue you're describing.

You can try putting a wait(0); before the draw_hard_map/draw_hard_sprite line, sometimes that fixes things that don't want to work properly. If that doesn't work, I can't figure out what's going on without seeing it for myself.