Re-write was a write-off. The whole concept is just not suitable for time-scaling.
(With my limited brainpower anyway, too long since school for this aging old brain)

Heres what Ive got so far.
Its basically done, visvosity works well,
but I just cant get the size-scale-factor to work right.
That is, getting the ripples to "spread" out faster or slower.

Oh, yeah. Looking at the code code, you'll see a new line of array elements
being added to tmp. The 'original' code you gave me calculated this
average based on the 4 up-down-left-right vertices.
My additional line now takes the diagonal vertices into account too.
Give the ripples a much more circular pattern...

Feel free to play and comment or suggest.
Any questions welcome too.
Im going to rest from this problem for a few hours, but Im still around.
Enjoy.
Code:
#include <acknex.h>
#include <default.c>


#define	scale		skill1		//INPUT/OUTPUT  - scale of the terrain
#define	viscosity		skill2		//INPUT/OUTPUT  - "density" of the fluid.  1=Water, 2=EngineOil, 3=Honey
#define	vertex_wide	skill3		//OUTPUT - width of HMP in vertices
#define	vertex_high	skill4		//OUTPUT - height of HMP in vertices

action fluid_action()
{
	//validate if a valid entity for fluid simulation (must be a terrain)
	if(!ent_status(my,2)||!ent_status(my,3))	return;		//this is NOT a terrain.
	//create and initialise "workspace" variables & pointers
	CONTACT* c;		
	var x, y, f, tmp, frametime=0;
	var size_x=ent_status(my,2)+1, size_y=ent_status(my,3)+1;
	//create and initialise "workspace" arrays
	var ***data = malloc(sizeof(var)*2);
	for(f=0; f<2; f++)	
	{	data[f] = malloc(sizeof(var)*size_x);
		for(x=0; x<size_x; x++)	
		{	(data[f])[x] = malloc(sizeof(var)*size_y);
			for(y=0; y<size_y; y++)		((data[f])[x])[y]  = 0;
	}	}
	//setup feedback skills
	if(!my.scale)	
	{
		//auto-calculate  scale based on VETs idea.
		c = ent_getvertex(my,NULL,1);
		x=c.v.x;	y=c.v.z;
		c = ent_getvertex(my,NULL,2+size_y);
		x-=c.v.x;	y-=c.v.z;
		my.scale = (abs(x) + abs(y))/2/2.54;	//quants per "square"  (2.54qu = scale of 1.0)
	}
	if(!my.viscosity)	my.viscosity = 1;		//default to "water" viscosity
	my.vertex_wide  = size_x;
	my.vertex_high	= size_y;
	//
	var sim_fps	= 10;	//Simulation FPS. AVOID changing if possible, because
	//					//if changed, it will skew BOTH Scale & Viscosity ranges
	//
	while(me)
	{	
		my.scale=clamp(my.scale,0.5,50);
		frametime += time_frame;
		if(frametime>(16/sim_fps*my.scale*2))
		{
			frametime -= (16/sim_fps*(my.scale*2));
			f = !f;
			my.viscosity=clamp(my.viscosity,0.9,5);
			for(y=1; y<(size_y-1); y++)   for(x=1; x<(size_x-1); x++)   
			{	
				c = ent_getvertex(my,NULL,(y*size_x)+x+1);    
				if((c.v.y!=((data[0])[x])[y])&&(c.v.y!=((data[1])[x])[y]))
				{	((data[f])[x])[y] = ((data[!f])[x])[y] = c.v.y;
					c = ent_getvertex(my,NULL,((y--)*size_x)+(x--)+1);		}
				tmp  = (((data[!f])[x-1])[y]+((data[!f])[x+1])[y]+((data[!f])[x])[y-1]+((data[!f])[x])[y+1]);
				tmp += (((data[!f])[x-1])[y-1]+((data[!f])[x-1])[y+1]+((data[!f])[x+1])[y-1]+((data[!f])[x+1])[y+1])/2;
				((data[f])[x])[y] = ((tmp/4*(my.scale))-((data[f])[x])[y])*(0.3*(3/my.viscosity));
				((data[f])[x])[y] = c.v.y = integer(((data[f])[x])[y]*10000)/10000;	//idle-damping
				ent_setvertex(my,c,(y*size_x)+x+1);
			}
		}		
		wait(1);
	}	
	//cleanup "workspace" arrays
	for(x=0; x<size_x; x++)	{   free((data[0])[x]);   free((data[1])[x]);   }
	free(data[0]);		free(data[1]);	 	free(data);	 
}



ENTITY* waterent;

void poke()
{
	CONTACT* c = ent_getvertex(waterent,NULL,210);    
	c.v.y += 5;
	ent_setvertex(waterent,c,510);
}


function main()
{
	video_mode = 10;
//	video_screen = 1;
	level_load("");
	vec_set(camera.x,   vector(0,25,25));
	vec_set(camera.pan, vector(270,-45,0));
	waterent = ent_create("waterent.hmp", nullvector, fluid_action);

	on_cuu = poke;

}
//




"There is no fate but what WE make." - CEO Cyberdyne Systems Corp.
A8.30.5 Commercial