示例#1
0
// Create some particle fire
void create_fire(VECT pos) {
	VECT ppos = pos;

	// Create some particle fire
	for(int i=0; i<RAND(3,7); i++) {
		ppos = pos;
		ppos.x += RANDF(-0.4f, 0.4f);
		ppos.y += RANDF(-0.3f, 0.3f);
		ppos.z += RANDF(-0.4f, 0.4f);
		VECT dir(RANDF(-0.01f,0.01f), RANDF(0.05f,0.15f), RANDF(-0.01f,0.01f));
		float c1[4] = { 1, 0.5f, 0.1f, 1 };
		float c2[4] = { 1, 0.1f, 0.1f, 0.1f };
		add_particle(ppos, dir, RAND(20,35), 0.3f, 0.1f, c1, c2, part_fire);
	}

	// Create smoke
	if(RAND(0,100) > 50) {
		pos.y += 0.2f;
		pos.x += RANDF(-0.3f, 0.3f);
		pos.y += RANDF(0.1f, 0.5f);
		pos.z += RANDF(-0.3f, 0.3f);
		VECT dir(RANDF(-0.01f,0.01f), RANDF(0.05f,0.1f), RANDF(-0.01f,0.01f));
		float c1[4] = { 0.5f, 0.1f, 0.1f, 1 };
		float c2[4] = { 0.1f, 0.1f, 0.1f, 0 };
		add_particle(pos, dir, RAND(20,35), 0.2f, 0.4f, c1, c2, part_smoke, true);
	}
}
示例#2
0
// Create the teleport effect
void create_teleport_effect(int x, int y) {

	// Add the big glow particle
	VECT pos(x + 0.5f, 0.5f, y + 0.5f);
	VECT dir = 0.0f;
	float c1[4] = { 1.0f, 1.0f, 0.3f, 1.0f };
	float c2[4] = { 1, 1, 0, 0 };
//	float c1[4] = { 0.3f, 0.8f, 1.0f, 1.0f };
//	float c2[4] = { 0, 0, 1, 0 };
	add_particle(pos, dir, 60, 2.0f, 1.0f, c1, c2, part_glow);

	// Create those "fire lines"
	for(int f=0; f < RAND(5,6); f++) {
	    // Choose the direction
		VECT dir;
		dir.x = RANDF(-0.5f, 0.5f);
		dir.y = RANDF(0.05f, 0.5f);
		dir.z = RANDF(-0.5f, 0.5f);
		normalize(dir);

		// Create the particles
		int max = RAND(25, 50);
		for(int i=0; i < max; i++) {
			VECT p(x + 0.5f, 0.0f, y + 0.5f);
			p += (dir * (float)i * 0.1f);
			VECT d = 0.0f;
			float s = (float)i / (float)max;
			add_particle(p, d, RAND(40,80), 0.5f * (1.0f-s), 0.00f, c1, c2, part_glow);
		}

	}

}
示例#3
0
文件: Tree.cpp 项目: spencerw/nbody
void add_particle(Node* n, Particle* p) {
  // Occupy empty node
  if (n->c1 == NULL && n->p == NULL) {
    n->p = p;
    n->child_mass = p->mass;
    n->com = p->pos;
  }
  // Traverse internal node
  else if (n->c1 != NULL) {
    n->child_mass += p->mass;
    n->com += p->pos*p->mass/n->child_mass;
    Node* insert_node = which_octant(n, p);
    add_particle(insert_node, p);
  }
  // Split external node
  else {
    split_external_node(n);
    Particle* pt = n->p;
    n->p = NULL;
    n->child_mass = p->mass + pt->mass;
    n->com = (p->pos*p->mass+pt->pos*pt->mass)/n->child_mass;
    Node* insert_node_original = which_octant(n, pt);
    Node* insert_node_new = which_octant(n, p);

    insert_node_original->child_mass = pt->mass;
    insert_node_original->com = pt->pos;
    insert_node_original->p = pt;

    add_particle(insert_node_new, p);
  }
}
示例#4
0
文件: game.c 项目: noox/Raketka
//funkce obstara vybuch raketky pri 0 hp
void player_explosion(float posx, float posy) { 
	int i;
	for (i=0;i<160;i++)
		add_particle(posx, posy, 50*DFRAND, 50*DFRAND, 2*FRAND, 1, FRAND, 0.1, 1);
	for (i=0;i<110;i++)
		add_particle(posx, posy, 150*DFRAND, 150*DFRAND, 3*FRAND, 1, FRAND, 0.5, 2);
	for (i=0;i<115;i++)
		add_particle(posx+10*DFRAND, posy+10*DFRAND, 10*DFRAND, 10*DFRAND, 6*FRAND, 0.5, 0.5, 0.5, 3);
	for (i=0;i<160;i++)
		add_particle(posx, posy, 50*DFRAND, 50*DFRAND, 2*FRAND, 1, 0.5*FRAND, 0.1, 3);
}
示例#5
0
void insert (Node* root, Particle *p )
{
 
  if (root->is_leaf)
    {
      if (root->particle)
	{
	  Node * child;
	  while (1)
	    {
	      child = split (root, p);
	      if (child->particle)
		root = child;
	      else
		break;
	    }
	  add_particle (child, p);
	}
      else
	{
	  add_particle (root, p);
	}
    }
  else
    {
      switch (child_alternative (root, p))
	{
	case ONE:
	  insert (root->one, p);
	  break;
	case TWO:
	  insert (root->two, p);
	  break;
	case THREE:
	  insert (root->three, p);
	  break;
	case FOUR:
	  insert (root->four, p);
	  break;
	default:
	  printf ("ERROR: Bad number of children\n");
	  finalize ();
	  exit (1);

	}
    }

}
示例#6
0
文件: foe.c 项目: mpersano/protozoa
static void
foe_add_trail(const vector2 *pos, const vector2 *dir, int palette)
{
	const int nparticles = 3 + irand(7);
	int i;
	vector2 tp = *pos, e = *dir;
	vec2_mul_scalar(&e, 1.02f);
	vec2_sub_from(&tp, &e);

	for (i = 0; i < nparticles; i++) {
		particle *p = add_particle();

		if (!p)
			break;

		p->ttl = 15 + irand(15);
		p->t = 0;
		p->palette = palette;
		p->width = p->height = .2f + .1f*frand();
		p->pos.x = tp.x + .2f*frand() - .1f;
		p->pos.y = tp.y + .2f*frand() - .1f;
		vec2_set(&p->dir, 1, 0);
		p->speed = 0.f;
		p->friction = .9f;
	}
}
示例#7
0
void SPHSystem::init_system()
{
	float3 pos;
	float3 vel=make_float3(0.0f);

	for(pos.x=world_size.x*0.0f; pos.x<world_size.x*0.6f; pos.x+=(kernel[LEVEL1]*0.5f))
	{
		for(pos.y=world_size.y*0.0f; pos.y<world_size.y*1.0f; pos.y+=(kernel[LEVEL1]*0.5f))
		{
			for(pos.z=world_size.z*0.0f; pos.z<world_size.z*1.0f; pos.z+=(kernel[LEVEL1]*0.5f))
			{
				add_particle(pos, vel, LEVEL1);
			}
		}
	}

	/*for(pos.x=world_size.x*0.7f; pos.x<world_size.x*1.0f; pos.x+=(kernel[LEVEL2]*0.5f))
	{
		for(pos.y=world_size.y*0.0f; pos.y<world_size.y*1.0f; pos.y+=(kernel[LEVEL2]*0.5f))
		{
			for(pos.z=world_size.z*0.0f; pos.z<world_size.z*1.0f; pos.z+=(kernel[LEVEL2]*0.5f))
			{
				add_particle(pos, vel, 1);
			}
		}
	}*/

	printf("Init Particle: %u\n", num_particle);
}
示例#8
0
void SpringSystem::add_cloth(const vec3& center, const vec3& x, const vec3& y, size_t size, float particleMass, int attach)
{
    assert(size > 1);
    
    size_t p0 = particles.size();
    cloths.push_back(ClothInfo(p0, size));

    // particles
    // 0 1 2 3 4 5
    // 6 7 8 9 ...
    for(size_t i=0; i<size; i++) {
        for(size_t j=0; j<size; j++) {
            bool attached = false;
            if (attach == 1)
                attached = (i == 0);
            else if (attach == 2)
                attached = (i == 0 || i == size-1 || j == 0 || j == size-1);
            add_particle(center + x * ((float)i / size) + y * ((float)j / size), vec3(0.0, 0.0, 0.0), particleMass, attached);
        }
    }

    // horizontal springs
    for(size_t i=0; i<size; i++) {
        for(size_t j=0; j<size-1; j++) {
            int from = p0 + i*size + j;
            int to   = from + 1;
            add_spring(from, to);
        }
    }

    // lateral springs
    for(size_t i=0; i<size-1; i++) {
        for(size_t j=0; j<size; j++) {
            int from = p0 + i*size + j;
            int to   = from + size;
            add_spring(from, to);
        }
    }

    // diagonal upper left to lower right
    for(size_t i=0; i<size-1; i++) {
        for(size_t j=0; j<size-1; j++) {
            int from = p0 + i*size + j;
            int to   = from + size + 1;
            add_spring(from, to);
        }
    }

    // diagonal upper right to lower left
    for(size_t i=0; i<size-1; i++) {
        for(size_t j=1; j<size; j++) {
            int from = p0 + i*size + j;
            int to   = from + size - 1;
            add_spring(from, to);
        }
    }
}
示例#9
0
//指定雪花区域与雪花数量,大小,缓存大小,片段大小			P244
SNOW::SNOW(BOUNDINGBOX *box,int num_particles):_box(*box)
{
	_size = 50.0f;							//雪花的大小
	_vertexbuf_size = 2048;					//粒子系统对GPU的可用大小
	_vertexbuf_offset = 0;					//顶点缓存的偏移量
	_vertexbuf_num = 512;					//每次填充顶点缓存顶点数
	for(int i = 0;i < num_particles;i++)	//根据所需数量添加雪花
		add_particle();
}
示例#10
0
FIRE::FIRE(D3DXVECTOR3 *origin,int num_particles)
{
	_origin				= *origin;
	_size				= 0.9f;
	_vertexbuf_size     = 2048;
	_vertexbuf_offset   = 0;   
	_vertexbuf_num		= 512; 
	for(int i = 0; i < num_particles; i++)
		add_particle();	
}
示例#11
0
文件: Tree.cpp 项目: spencerw/nbody
Tree::Tree(Particle* p, int _n_particles, double _theta, Physics* _physics) {
  n_particles = _n_particles;
  theta = _theta;
  physics = _physics;

  double box_length = max_boxsize(p, n_particles);
  std::cout << "Constructing tree of boxsize " << box_length << std::endl;
  root = new Node(-box_length, box_length, -box_length, box_length, -box_length, box_length);
  int i;
  for (i = 0; i < n_particles; i++) {
    add_particle(root, &p[i]);
  }
  std::cout << "Tree finished" << std::endl;
}
示例#12
0
void SPHSystem::init_system()
{
	srand((unsigned int)time(NULL));

	float2 pos;
	float2 vel=make_float2(0.0f, 0.0f);

	for(pos.x=hParam->world_size.x*0.0f; pos.x<hParam->world_size.x*0.4f; pos.x+=(hParam->kernel*0.6f))
	{
		for(pos.y=hParam->world_size.y*0.0f; pos.y<hParam->world_size.y*0.9f; pos.y+=(hParam->kernel*0.6f))
		{
			add_particle(pos, vel);
		}
	}

	copy_array(dMem, hMem, sizeof(Particle)*hParam->num_particle, CUDA_HOST_TO_DEV);
	printf("Init Particle: %u\n", hParam->num_particle);
}
示例#13
0
void run_simulation(particle_t* ps, int n, FILE* fsave){
  //Create partition and set active
  partition* p = alloc_partition(n);
  set_active_partition(p);

  //Add all particles
  for(int i=0; i<n; i++)
    add_particle(&ps[i]);

  //For each step
  for(int step = 0; step < NSTEPS; step++ ){
    update_particles();
    
    //=== Save state to file ===
    if( fsave && (step%SAVEFREQ) == 0 )
      save( fsave, n, particles );
  }
}
示例#14
0
void SPHSystem::init_system()
{
	float3 pos;
	float3 vel;

	vel.x=0.0f;
	vel.y=0.0f;
	vel.z=0.0f;

	for(pos.x=world_size.x*0.0f; pos.x<world_size.x*0.6f; pos.x+=(kernel*0.5f))
	{
		for(pos.y=world_size.y*0.0f; pos.y<world_size.y*0.9f; pos.y+=(kernel*0.5f))
		{
			for(pos.z=world_size.z*0.0f; pos.z<world_size.z*0.6f; pos.z+=(kernel*0.5f))
			{
				add_particle(pos, vel);
			}
		}
	}

	printf("Init Particle: %u\n", num_particle);
}
示例#15
0
static void
gen_explosion(float x, float y)
{
	int i, n, c;
	particle *p;

	n = 150 + irand(150);
	c = irand(NUM_PALETTES);

	for (i = 0; i < n; i++) {
		vector2 offs;

		p = add_particle();

		if (!p)
			break;

		p->ttl = 20 + irand(20);
		p->t = 0;
		p->width = .3f*(.6f + .1f*frand());
		p->height = .3f*(2.8f + .4f*frand());
		p->pos.x = x;
		p->pos.y = y;
		p->palette = c;

		vec2_set(&p->dir, frand() - .5f, frand() - .5f);
		vec2_normalize(&p->dir);

		offs = p->dir;
		vec2_mul_scalar(&offs, 1.3f*frand());
		vec2_add_to(&p->pos, &offs);

		p->speed = PARTICLE_SPEED + .05f*frand();
		p->friction = .96f;
	}
}
示例#16
0
文件: track.c 项目: yosefm/openptv
/*     track backwards */
double trackback_c (tracking_run *run_info, int step)
{
    int i, j, h, in_volume = 0;
    int philf[4][MAX_CANDS];
    int count1 = 0, count2 = 0, num_added = 0;
    int quali = 0;
    double angle, acc, dl;
    vec3d diff_pos, X[6];     /* 6 reference points used in the algorithm */
    vec2d n[4], v2[4];     // replaces xn,yn, x2[4], y2[4],
    double rr, Ymin = 0, Ymax = 0;
    double npart = 0, nlinks = 0;
    foundpix *w;

    sequence_par *seq_par;
    track_par *tpar;
    volume_par *vpar;
    control_par *cpar;
    framebuf *fb;
    Calibration **cal;

    /* Shortcuts to inside current frame */
    P *curr_path_inf, *ref_path_inf;

    /* shortcuts */
    cal = run_info->cal;
    seq_par = run_info->seq_par;
    tpar = run_info->tpar;
    vpar = run_info->vpar;
    cpar = run_info->cpar;

    fb = run_info->fb;

    /* Prime the buffer with first frames */
    for (step = seq_par->last; step > seq_par->last - 4; step--) {
        fb_read_frame_at_end(fb, step, 1);
        fb_next(fb);
    }
    fb_prev(fb);

    /* sequence loop */
    for (step = seq_par->last - 1; step > seq_par->first; step--) {
        printf ("Time step: %d, seqnr: %d:\n",
                step - seq_par->first, step);

        for (h = 0; h < fb->buf[1]->num_parts; h++) {
            curr_path_inf = &(fb->buf[1]->path_info[h]);

            /* We try to find link only if the forward search failed to. */
            if ((curr_path_inf->next < 0) || (curr_path_inf->prev != -1)) continue;

            for (j = 0; j < 6; j++) vec_init(X[j]);
            curr_path_inf->inlist = 0;

            /* 3D-position of current particle */
            vec_copy(X[1], curr_path_inf->x);

            /* use information from previous to locate new search position
               and to calculate values for search area */
            ref_path_inf = &(fb->buf[0]->path_info[curr_path_inf->next]);
            vec_copy(X[0], ref_path_inf->x);
            search_volume_center_moving(ref_path_inf->x, curr_path_inf->x, X[2]);
            
            for (j = 0; j < fb->num_cams; j++) {
                point_to_pixel (n[j], X[2], cal[j], cpar);
            }
            
            /* calculate searchquader and reprojection in image space */
            w = sorted_candidates_in_volume(X[2], n, fb->buf[2], run_info);
            
            if (w != NULL) {
                count2++;

                i = 0;
                while (w[i].ftnr != TR_UNUSED) {
                    ref_path_inf = &(fb->buf[2]->path_info[w[i].ftnr]);
                    vec_copy(X[3], ref_path_inf->x);

                    vec_subt(X[1], X[3], diff_pos);
                    if (pos3d_in_bounds(diff_pos, tpar)) {
                        angle_acc(X[1], X[2], X[3], &angle, &acc);

                        /* *********************check link *****************************/
                        if ((acc < tpar->dacc && angle < tpar->dangle) || \
                            (acc < tpar->dacc/10))
                        {
                            dl = (vec_diff_norm(X[1], X[3]) +
                                  vec_diff_norm(X[0], X[1]) )/2;
                            quali = w[i].freq;
                            rr = (dl/run_info->lmax + acc/tpar->dacc + \
                                angle/tpar->dangle)/quali;
                            register_link_candidate(curr_path_inf, rr, w[i].ftnr);
                        }
                    }
                    i++;
                }
            }

            free(w);

            /* if old wasn't found try to create new particle position from rest */
            if (tpar->add) {
                if ( curr_path_inf->inlist == 0) {
                    quali = assess_new_position(X[2], v2, philf, fb->buf[2], run_info);
                    if (quali>=2) {
                        //vec_copy(X[3], X[2]);
                        in_volume = 0;

                        point_position(v2, fb->num_cams, cpar->mm, cal, X[3]);

                        /* volume check */
                        if ( vpar->X_lay[0] < X[3][0] && X[3][0] < vpar->X_lay[1] &&
                             Ymin < X[3][1] && X[3][1] < Ymax &&
                             vpar->Zmin_lay[0] < X[3][2] && X[3][2] < vpar->Zmax_lay[1])
                        {in_volume = 1;}

                        vec_subt(X[1], X[3], diff_pos);
                        if (in_volume == 1 && pos3d_in_bounds(diff_pos, tpar)) {
                            angle_acc(X[1], X[2], X[3], &angle, &acc);

                            if ( (acc<tpar->dacc && angle<tpar->dangle) || \
                                 (acc<tpar->dacc/10) )
                            {
                                dl = (vec_diff_norm(X[1], X[3]) +
                                      vec_diff_norm(X[0], X[1]) )/2;
                                rr = (dl/run_info->lmax+acc/tpar->dacc + angle/tpar->dangle)/(quali);
                                register_link_candidate(curr_path_inf, rr, fb->buf[2]->num_parts);

                                add_particle(fb->buf[2], X[3], philf);
                            }
                        }
                        in_volume = 0;
                    }
                }
            }             /* end of if old wasn't found try to create new particle position from rest */
        }         /* end of h-loop */

        for (h = 0; h < fb->buf[1]->num_parts; h++) {
            curr_path_inf = &(fb->buf[1]->path_info[h]);

            if(curr_path_inf->inlist > 0 ) {
                sort(curr_path_inf->inlist, (float *)curr_path_inf->decis,
                     curr_path_inf->linkdecis);
            }
        }

        /* create links with decision check */
        count1 = 0; num_added = 0;
        for (h = 0; h < fb->buf[1]->num_parts; h++) {
            curr_path_inf = &(fb->buf[1]->path_info[h]);

            if (curr_path_inf->inlist > 0 ) {
                /* if old/new and unused prev == -1 and next == -2 link is created */
                ref_path_inf = &(fb->buf[2]->path_info[curr_path_inf->linkdecis[0]]);

                if ( ref_path_inf->prev == PREV_NONE && \
                     ref_path_inf->next == NEXT_NONE )
                {
                    curr_path_inf->finaldecis = curr_path_inf->decis[0];
                    curr_path_inf->prev = curr_path_inf->linkdecis[0];
                    fb->buf[2]->path_info[curr_path_inf->prev].next = h;
                    num_added++;
                }

                /* old which link to prev has to be checked */
                if ((ref_path_inf->prev != PREV_NONE) && \
                    (ref_path_inf->next == NEXT_NONE) )
                {
                    vec_copy(X[0], fb->buf[0]->path_info[curr_path_inf->next].x);
                    vec_copy(X[1], curr_path_inf->x);
                    vec_copy(X[3], ref_path_inf->x);
                    vec_copy(X[4], fb->buf[3]->path_info[ref_path_inf->prev].x);
                    for (j = 0; j < 3; j++)
                        X[5][j] = 0.5*(5.0*X[3][j] - 4.0*X[1][j] + X[0][j]);

                    angle_acc(X[3], X[4], X[5], &angle, &acc);

                    if ( (acc<tpar->dacc && angle<tpar->dangle) ||  (acc<tpar->dacc/10) ) {
                        curr_path_inf->finaldecis = curr_path_inf->decis[0];
                        curr_path_inf->prev = curr_path_inf->linkdecis[0];
                        fb->buf[2]->path_info[curr_path_inf->prev].next = h;
                        num_added++;
                    }
                }
            }

            if (curr_path_inf->prev != PREV_NONE ) count1++;
        }         /* end of creation of links with decision check */

        printf ("step: %d, curr: %d, next: %d, links: %d, lost: %d, add: %d",
                step, fb->buf[1]->num_parts, fb->buf[2]->num_parts, count1,
                fb->buf[1]->num_parts - count1, num_added);

        /* for the average of particles and links */
        npart = npart + fb->buf[1]->num_parts;
        nlinks = nlinks + count1;

        fb_next(fb);
        fb_write_frame_from_start(fb, step);
        if(step > seq_par->first + 2) { fb_read_frame_at_end(fb, step - 3, 1); }
    }     /* end of sequence loop */

    /* average of all steps */
    npart /= (seq_par->last - seq_par->first - 1);
    nlinks /= (seq_par->last - seq_par->first - 1);

    printf ("Average over sequence, particles: %5.1f, links: %5.1f, lost: %5.1f\n",
            npart, nlinks, npart-nlinks);

    fb_next(fb);
    fb_write_frame_from_start(fb, step);

    fb_free(fb);
    free(fb);
    free(tpar);

    return nlinks;
}
示例#17
0
文件: track.c 项目: yosefm/openptv
/* trackcorr_c_loop is the main tracking subroutine that scans the 3D particle position
 * data from rt_is.* files and the 2D particle positions in image space in _targets and
 * constructs trajectories (links) of the particles in 3D in time.
 * the basic concepts of the tracking procedure are from the following publication by
 * Jochen Willneff: "A New Spatio-Temporal Matching Algorithm For 3D-Particle Tracking Velocimetry"
 * https://www.mendeley.com/catalog/new-spatiotemporal-matching-algorithm-3dparticle-tracking-velocimetry/
 * or http://e-collection.library.ethz.ch/view/eth:26978
 * this method is an extension of the previously used tracking method described in details in
 * Malik et al. 1993: "Particle tracking velocimetry in three-dimensional flows: Particle tracking"
 * http://mnd.ly/2dCt3um
 *
 * Arguments:
 * tracking_run *run_info pointer to the (sliding) frame dataset of 4 frames of particle positions
 * and all the needed parameters underneath: control, volume, etc.
 * integer step number or the frame number from the sequence
 * Note: step is not really setting up the step to track, the buffer provided to the trackcoor_c_loop
 * is already preset by 4 frames buf[0] to buf[3] and we track particles in buf[1], i.e. one "previous"
 * one present and two future frames.
 * 
 * Returns: function does not return an argument, the tracks are updated within the run_info dataset
 */
void trackcorr_c_loop (tracking_run *run_info, int step) {
    /* sequence loop */
    int j, h, mm, kk, in_volume = 0;
    int philf[4][MAX_CANDS];
    int count1 = 0, count2 = 0, count3 = 0, num_added = 0;
    int quali = 0;
    vec3d diff_pos, X[6];     /* 7 reference points used in the algorithm, TODO: check if can reuse some */
    double angle, acc, angle0, acc0,  dl;
    double angle1, acc1;
    vec2d v1[4], v2[4]; /* volume center projection on cameras */ 
    double rr;


    /* Shortcuts to inside current frame */
    P *curr_path_inf, *ref_path_inf;
    corres *curr_corres;
    target **curr_targets;
    int _ix;     /* For use in any of the complex index expressions below */
    int orig_parts; /* avoid infinite loop with particle addition set */

    /* Shortcuts into the tracking_run struct */ 
    Calibration **cal;
    framebuf *fb;
    track_par *tpar;
    volume_par *vpar;
    control_par *cpar;

    foundpix *w, *wn; 
    count1 = 0; num_added = 0;

    fb = run_info->fb;
    cal = run_info->cal;
    tpar = run_info->tpar;
    vpar = run_info->vpar;
    cpar = run_info->cpar;
    curr_targets = fb->buf[1]->targets;

    /* try to track correspondences from previous 0 - corp, variable h */
    orig_parts = fb->buf[1]->num_parts;
    for (h = 0; h < orig_parts; h++) {
        for (j = 0; j < 6; j++) vec_init(X[j]);

        curr_path_inf = &(fb->buf[1]->path_info[h]);
        curr_corres = &(fb->buf[1]->correspond[h]);

        curr_path_inf->inlist = 0;

        /* 3D-position */
        vec_copy(X[1], curr_path_inf->x);

        /* use information from previous to locate new search position
           and to calculate values for search area */
        if (curr_path_inf->prev >= 0) {
            ref_path_inf = &(fb->buf[0]->path_info[curr_path_inf->prev]);
            vec_copy(X[0], ref_path_inf->x);
            search_volume_center_moving(ref_path_inf->x, curr_path_inf->x, X[2]);

            for (j = 0; j < fb->num_cams; j++) {
                point_to_pixel (v1[j], X[2], cal[j], cpar);
            }
        } else {
            vec_copy(X[2], X[1]);
            for (j = 0; j < fb->num_cams; j++) {
                if (curr_corres->p[j] == -1) {
                    point_to_pixel (v1[j], X[2], cal[j], cpar);
                } else {
                    _ix = curr_corres->p[j];
                    v1[j][0] = curr_targets[j][_ix].x;
                    v1[j][1] = curr_targets[j][_ix].y;
                }
            }

        }

        /* calculate search cuboid and reproject it to the image space */
        w = sorted_candidates_in_volume(X[2], v1, fb->buf[2], run_info);
        if (w == NULL) continue;

        /* Continue to find candidates for the candidates. */
        count2++;
        mm = 0;
        while (w[mm].ftnr != TR_UNUSED) {       /* counter1-loop */
            /* search for found corr of current the corr in next
               with predicted location */

            /* found 3D-position */
            ref_path_inf = &(fb->buf[2]->path_info[w[mm].ftnr]);
            vec_copy(X[3], ref_path_inf->x);

            if (curr_path_inf->prev >= 0) {
                for (j = 0; j < 3; j++)
                    X[5][j] = 0.5*(5.0*X[3][j] - 4.0*X[1][j] + X[0][j]);
            } else {
                search_volume_center_moving(X[1], X[3], X[5]);
            }

            for (j = 0; j < fb->num_cams; j++) {
                point_to_pixel (v1[j], X[5], cal[j], cpar);
            }

            /* end of search in pix */
            wn = sorted_candidates_in_volume(X[5], v1, fb->buf[3], run_info);
            if (wn != NULL) {
                count3++;
                kk = 0;
                while (wn[kk].ftnr != TR_UNUSED) {
                    ref_path_inf = &(fb->buf[3]->path_info[wn[kk].ftnr]);
                    vec_copy(X[4], ref_path_inf->x);

                    vec_subt(X[4], X[3], diff_pos);
                    if ( pos3d_in_bounds(diff_pos, tpar)) {
                        angle_acc(X[3], X[4], X[5], &angle1, &acc1);
                        if (curr_path_inf->prev >= 0) {
                            angle_acc(X[1], X[2], X[3], &angle0, &acc0);
                        } else {
                            acc0 = acc1; angle0 = angle1;
                        }

                        acc = (acc0+acc1)/2; angle = (angle0+angle1)/2;
                        quali = wn[kk].freq+w[mm].freq;

                        if ((acc < tpar->dacc && angle < tpar->dangle) || \
                            (acc < tpar->dacc/10))
                        {
                            dl = (vec_diff_norm(X[1], X[3]) +
                                vec_diff_norm(X[4], X[3]) )/2;
                            rr = (dl/run_info->lmax + acc/tpar->dacc + \
                                angle/tpar->dangle)/(quali);
                            register_link_candidate(
                                curr_path_inf, rr, w[mm].ftnr);
                        }
                    }
                    kk++;
                } /* End of searching 2nd-frame candidates. */
            }             

            /* creating new particle position,
             *  reset img coord because of num_cams < 4
             *  fix distance of 3 pixels to define xl,xr,yu,yd instead of searchquader
             *  and search for unused candidates in next time step
             */
            quali = assess_new_position(X[5], v2, philf, fb->buf[3], run_info); 
                        
            /* quali >=2 means at least in two cameras
             * we found a candidate
             */
            if ( quali >= 2) {
                in_volume = 0;                 //inside volume

                dl = point_position(v2, cpar->num_cams, cpar->mm, cal, X[4]);

                /* volume check */
                if ( vpar->X_lay[0] < X[4][0] && X[4][0] < vpar->X_lay[1] &&
                     run_info->ymin < X[4][1] && X[4][1] < run_info->ymax &&
                     vpar->Zmin_lay[0] < X[4][2] && X[4][2] < vpar->Zmax_lay[1])
                {
                    in_volume = 1;
                }

                vec_subt(X[3], X[4], diff_pos);
                if ( in_volume == 1 && pos3d_in_bounds(diff_pos, tpar) ) {
                    angle_acc(X[3], X[4], X[5], &angle, &acc);

                    if ((acc < tpar->dacc && angle < tpar->dangle) || \
                        (acc < tpar->dacc/10))
                    {
                        dl = (vec_diff_norm(X[1], X[3]) +
                              vec_diff_norm(X[4], X[3]) )/2;
                        rr = (dl/run_info->lmax + acc/tpar->dacc + angle/tpar->dangle) /
                             (quali+w[mm].freq);
                        register_link_candidate(curr_path_inf, rr, w[mm].ftnr);

                        if (tpar->add) {
                            add_particle(fb->buf[3], X[4], philf);
                            num_added++;
                        }
                    }
                }
                in_volume = 0;
            }
            quali = 0;

            /* end of creating new particle position */
            /* *************************************************************** */

            /* try to link if kk is not found/good enough and prev exist */
            if ( curr_path_inf->inlist == 0 && curr_path_inf->prev >= 0 ) {
                vec_subt(X[3], X[1], diff_pos);

                if (pos3d_in_bounds(diff_pos, tpar)) {
                    angle_acc(X[1], X[2], X[3], &angle, &acc);

                    if ( (acc < tpar->dacc && angle < tpar->dangle) || \
                         (acc < tpar->dacc/10) )
                    {
                        quali = w[mm].freq;
                        dl = (vec_diff_norm(X[1], X[3]) +
                              vec_diff_norm(X[0], X[1]) )/2;
                        rr = (dl/run_info->lmax + acc/tpar->dacc + angle/tpar->dangle)/(quali);
                        register_link_candidate(curr_path_inf, rr, w[mm].ftnr);
                    }
                }
            }

            free(wn);
            mm++;
        } /* end of loop over first-frame candidates. */

        /* begin of inlist still zero */
        if (tpar->add) {
            if ( curr_path_inf->inlist == 0 && curr_path_inf->prev >= 0 ) {
                quali = assess_new_position(X[2], v2, philf, fb->buf[2], run_info);

                if (quali>=2) {
                    vec_copy(X[3], X[2]);
                    in_volume = 0;

                    dl = point_position(v2, fb->num_cams, cpar->mm, cal, X[3]);

                    /* in volume check */
                    if ( vpar->X_lay[0] < X[3][0] && X[3][0] < vpar->X_lay[1] &&
                         run_info->ymin < X[3][1] && X[3][1] < run_info->ymax &&
                         vpar->Zmin_lay[0] < X[3][2] &&
                         X[3][2] < vpar->Zmax_lay[1])
                    {
                        in_volume = 1;
                    }

                    vec_subt(X[2], X[3], diff_pos);
                    if ( in_volume == 1 && pos3d_in_bounds(diff_pos, tpar) ) {
                        angle_acc(X[1], X[2], X[3], &angle, &acc);

                        if ( (acc < tpar->dacc && angle < tpar->dangle) || \
                             (acc < tpar->dacc/10) )
                        {
                            dl = (vec_diff_norm(X[1], X[3]) +
                                  vec_diff_norm(X[0], X[1]) )/2;
                            rr = (dl/run_info->lmax + acc/tpar->dacc + angle/tpar->dangle)/(quali);
                            register_link_candidate(curr_path_inf, rr, fb->buf[2]->num_parts);

                            add_particle(fb->buf[2], X[3], philf);
                            num_added++;
                        }
                    }
                    in_volume = 0;
                }                 // if quali >= 2
            }
        }
        /* end of inlist still zero */
        /***********************************/

        free(w);
    }     /* end of h-loop */

    /* sort decis and give preliminary "finaldecis"  */
    for (h = 0; h < fb->buf[1]->num_parts; h++) {
        curr_path_inf = &(fb->buf[1]->path_info[h]);

        if(curr_path_inf->inlist > 0 ) {
            sort(curr_path_inf->inlist, (float *) curr_path_inf->decis,
                 curr_path_inf->linkdecis);
            curr_path_inf->finaldecis = curr_path_inf->decis[0];
            curr_path_inf->next = curr_path_inf->linkdecis[0];
        }
    }

    /* create links with decision check */
    for (h = 0; h < fb->buf[1]->num_parts; h++) {
        curr_path_inf = &(fb->buf[1]->path_info[h]);

        if(curr_path_inf->inlist > 0 ) {
            ref_path_inf = &(fb->buf[2]->path_info[curr_path_inf->next]);

            if (ref_path_inf->prev == PREV_NONE) {
                /* best choice wasn't used yet, so link is created */
                ref_path_inf->prev = h;
            } else {
                /* best choice was already used by mega[2][mega[1][h].next].prev */
                /* check which is the better choice */
                if ( fb->buf[1]->path_info[ref_path_inf->prev].finaldecis > \
                     curr_path_inf->finaldecis)
                {
                    /* remove link with prev */
                    fb->buf[1]->path_info[ref_path_inf->prev].next = NEXT_NONE;
                    ref_path_inf->prev = h;
                } else {
                    curr_path_inf->next = NEXT_NONE;
                }
            }
        }
        if (curr_path_inf->next != NEXT_NONE ) count1++;
    }
    /* end of creation of links with decision check */

    printf ("step: %d, curr: %d, next: %d, links: %d, lost: %d, add: %d\n",
            step, fb->buf[1]->num_parts, fb->buf[2]->num_parts, count1,
            fb->buf[1]->num_parts - count1, num_added);

    /* for the average of particles and links */
    run_info->npart = run_info->npart + fb->buf[1]->num_parts;
    run_info->nlinks = run_info->nlinks + count1;

    fb_next(fb);
    fb_write_frame_from_start(fb, step);
    if(step < run_info->seq_par->last - 2) {
        fb_read_frame_at_end(fb, step + 3, 0);
    }
} /* end of sequence loop */
示例#18
0
// Move the enemy
void ENEMY::move() {
	// Advance the animation
	if(!chase && !burning)
		anim += 0.10f;
	else
		anim += 0.20f;
	if((int)anim > 3 || kicked)
		anim = 0.0f;

	// Advance the dying animation if we're actually dying
	if(dying) {
		die_anim -= 0.03f;

		// Create the blue "burning down" effect
		float px = get_real_x();
		float py = get_real_y();
		for(int f=0; f < RAND(2,10); f++) {
			float rnd = RANDF(-0.3f, 0.3f);
			VECT pos(px, 2*size - 0.05f - (2.5f*size*(1-die_anim)), py);
			pos.x += rnd;
			pos.z -= rnd;
			if(pos.y < 0.0f)
				pos.y = 0.0f;
			if(turning)
				pos.y += (turning_raise * 0.85f);
			VECT dir = 0.0f;
			float c1[4] = { 0.1f, 0.7f, 1, 1 };
			float c2[4] = { 0.1f, 0.7f, 1, 0 };
			add_particle(pos, dir, RAND(20,35), 0.1f, 0.4f, c1, c2, part_star);
		}

		if(die_anim < 0.0f) {
			die_anim = 0.0f;
			alive = false;
		}

		return;
	}


	// Create some particle fire from the burning enemies
	if(burning) {
		VECT ppos(get_real_x(), 0.5f, get_real_y());
		create_fire(ppos);
	}

	// Advance the turning animation
	if(turning) {
		// Raise up
		if(turning == 1) {
			turning_raise += 0.035f;
			if(turning_raise >= 1.0f) {
				turning_raise = 1.0f;
				turning++;
			}
		}
		// Turn
		else if(turning == 2) {
			turning_counter++;
			if(turning_counter == 5) {
				dir = nextdir;
				nextdir = dir + 1;
				if(nextdir > DIR_W)
					nextdir = DIR_N;
			}
			else if(turning_counter == 10) {
				dir = nextdir;
				turning++;
			}
		}
		// Go down
		else if(turning == 3) {
			turning_raise -= 0.035f;
			if(turning_raise <= 0.0f) {
				turning_raise = 0.0f;
				turning = 0;
			}
		}

		// Check the collision between the player #1
		if(p1.alive && !p1.jumping) {
			float dx = get_real_x() - p1.get_real_x();
			float dy = get_real_y() - p1.get_real_y();
			if(dx*dx + dy*dy <= 0.9f) {
				// Collision happened!

				// Kill the player and die
				p1.die();
				die();
			}
		}

		// Check the collision between the player #2
		if(alive && two_players && p2.alive && !p2.jumping) {
			float dx = get_real_x() - p2.get_real_x();
			float dy = get_real_y() - p2.get_real_y();
			if(dx*dx + dy*dy <= 0.9f) {
				// Collision happened!

				// Kill the player and die
				p2.die();
				die();
			}
		}

		return;
	}


	// If there is the lightning special power in progress, don't move the enemies which are
	// suffering from the lightning strikes
	if(special_power_pause && which_special_power == BLUE_POWER_LIGHTNING) {
		// Check if we're a target
		for(int f=0; f<ENEMY_AMOUNT; f++) {
			if(sp_lightning.targets[f] == this) {
				anim += 0.30f;
				if((int)anim > 3)
					anim = 0.0f;
				return;
			}
		}
	}

	// Don't move if the level is finished
	if(level_pause)
		return;


	// Check the traps
	if(traplist.size() > 0) {
		list<TRAP>::iterator t;
		for(t = traplist.begin(); t != traplist.end(); ++t) {
			if(x == (*t).x && y == (*t).y) {
				die();
				return;
			}
		}
	}


	// Handle the burning, that is run around aimlessly
	if(burning) {
		if(!kicked) {
			// Reduce the burning time
			burn_time--;
			if(burn_time == 0) {
				die();
				return;
			}

			// Choose a random direction
			if(RAND(0,100) > 50 && offset == 0.0f) {
				if(RAND(0,100) > 50)
					dir++;
				else
					dir--;
				if(dir > DIR_W)
					dir = DIR_N;
				else if(dir < DIR_N)
					dir = DIR_W;
			}

			// Move one step
			if(tx == x && ty == y) {
				offset = 0.0f;

				// Don't stop until there's a wall.
				switch(dir) {
					default:
					case DIR_N: tx = x; ty = y - 1; break;
					case DIR_E: tx = x + 1; ty = y; break;
					case DIR_S: tx = x; ty = y + 1; break;
					case DIR_W: tx = x - 1; ty = y; break;
				}

				// Check if the target is passable?
				if(map_solid(tx, ty)) {
					// Stop and choose a new dir
					tx = x;
					ty = y;

					dir += RAND(-1,1);
					if(dir < DIR_N)
						dir = DIR_W;
					else if(dir > DIR_W)
						dir = DIR_N;
					return;
				}

			}

			// Move towards the target tile
			if(offset < 1.0f && (tx != x || ty != y)) {
				offset += speed;

				// Check the collision between the player #1
				if(p1.alive && !p1.jumping && !(using_special_power == 1 && which_special_power == BLUE_POWER_TELEPORT)) {
					float dx = get_real_x() - p1.get_real_x();
					float dy = get_real_y() - p1.get_real_y();
					if(dx*dx + dy*dy <= 0.9f) {
						// Collision happened!

						// Turn around and run
						tx = x;
						ty = y;
						offset = 0.0f;
						dir += 2;
						if(dir > DIR_W)
							dir -= 4;
					}
				}

				// Check the collision between the player #2
				if(two_players && p2.alive && !p2.jumping && !(using_special_power == 2 && which_special_power == BLUE_POWER_TELEPORT)) {
					float dx = get_real_x() - p2.get_real_x();
					float dy = get_real_y() - p2.get_real_y();
					if(dx*dx + dy*dy <= 0.9f) {
						// Collision happened!

						// Turn around and run
						tx = x;
						ty = y;
						offset = 0.0f;
						dir += 2;
						if(dir > DIR_W)
							dir -= 4;
					}
				}

				// Check the collision between the potato men
				if(potatoman.collide_with(this) && !kicked) {
					// Potatoman "kicked" us
					potatoman.kick(this);
				}


				// If we're reached the target tile, move again
				if(offset >= 1.0f) {
					x = tx;
					y = ty;
					offset = 0.0f;
				}
			}
		}

		// Check collisions with other enemies and spread the fire
		bool burnt_somebody = false;
		list<ENEMY>::iterator e;
		for(e = enemylist.begin(); e != enemylist.end(); ++e) {
			if(this != &(*e) && !(*e).burning) {
				// Check the distance
				float dx = get_real_x() - (*e).get_real_x();
				float dy = get_real_y() - (*e).get_real_y();
				if(dx*dx + dy*dy <= 0.9f) {
					// Burn the other enemy
					(*e).burning = true;
					(*e).burn_time = enemy_burn_time;
					(*e).speed += 0.06f;
					burnt_somebody = true;
				}
			}
		}

		// Play the burning sound
		if(burnt_somebody)
			play_sound(SND_WILDFIRE, false);

		if(!kicked)
			return;
	}


	// Not burning below here

	// Choose a random destination
	if(path_pos == -1) {
		// Choose a valid target
		int dx = RAND(0, MAP_W-1);
		int dy = RAND(0, MAP_H-1);
		while(map_solid(dx, dy) || dx == x || dy == y) {
			dx = RAND(0, MAP_W-1);
			dy = RAND(0, MAP_H-1);
		}

		// Calculate the path
		if(pf.find_path(x, y, dx, dy) == PATH_FAILED) {
			// Well, tough luck. We'll just wait and try again later.
			return;
		}

		// Now we've got a nice path for us!
		path_pos = 0;
		offset = 0.0f;
		tx = pf.path[0].x;
		ty = pf.path[0].y;
		dir = get_dir(tx - x, ty - y);
		look_player();
	}

	// Move one step
	if(tx == x && ty == y && path_pos > -1) {
		offset = 0.0f;

		// Follow the path if we're not chasing
		if(chase == 0 && !kicked) {
			path_pos++;
			tx = pf.path[path_pos].x;
			ty = pf.path[path_pos].y;
			dir = get_dir(tx - x, ty - y);
			look_player();
		}
		else if(chase && !kicked) {
			// We are chasing. Don't stop until there's a wall.
			switch(dir) {
				default:
				case DIR_N: tx = x; ty = y - 1; break;
				case DIR_E: tx = x + 1; ty = y; break;
				case DIR_S: tx = x; ty = y + 1; break;
				case DIR_W: tx = x - 1; ty = y; break;
			}

			// Check if the target is passable?
			if(map_solid(tx, ty)) {
				// Stop and choose a new path
				tx = x;
				ty = y;

				path_pos = -1;
				chase = 0;
				speed -= 0.03f;
			}
		}
		else if(kicked) {
			// Potatoman has kicked us. "Fly" straight until we hit a wall.
			switch(dir) {
				default:
				case DIR_N: tx = x; ty = y - 1; break;
				case DIR_E: tx = x + 1; ty = y; break;
				case DIR_S: tx = x; ty = y + 1; break;
				case DIR_W: tx = x - 1; ty = y; break;
			}

			// Check for the wall
			if(map_solid(tx, ty)) {
				die();
				return;
			}
		}
	}

	// Move towards the target tile
	if(offset < 1.0f && (tx != x || ty != y) && path_pos > -1) {
		offset += speed;

		// Check the collision between the player #1
		if(p1.alive && !p1.jumping && !(using_special_power == 1 && which_special_power == BLUE_POWER_TELEPORT)) {
			float dx = get_real_x() - p1.get_real_x();
			float dy = get_real_y() - p1.get_real_y();
			if(dx*dx + dy*dy <= 0.9f) {
				// Collision happened!

				// Kill the player and die
				p1.die();
				die();
			}
		}

		// Check the collision between the player #2
		if(alive && two_players && p2.alive && !p2.jumping && !(using_special_power == 2 && which_special_power == BLUE_POWER_TELEPORT)) {
			float dx = get_real_x() - p2.get_real_x();
			float dy = get_real_y() - p2.get_real_y();
			if(dx*dx + dy*dy <= 0.9f) {
				// Collision happened!

				// Kill the player and die
				p2.die();
				die();
			}
		}


		// Check the collision between the potato men
		if(potatoman.collide_with(this) && !kicked) {
			// Potatoman "kicked" us
			potatoman.kick(this);
		}


		// If we're reached the target tile, move again
		if(offset >= 1.0f) {
			x = tx;
			y = ty;
			offset = 0.0f;

			// If this is the final destination, stay put and choose a new path
			// on the next cycle
			if(x == pf.dx && y == pf.dy && !chase && !kicked)
				path_pos = -1;
		}
	}

}
示例#19
0
// Move the player
void PLAYER::move() {
#ifndef EDITOR
	int who = (this == &p1) ? 1 : 2;
	int who2 = who-1; 	// Used for array indices

	// Reduce the icon alpha
	if(p_icon_alpha[who2]) {
		p_icon_alpha[who2] -= 0.005f;
		if(p_icon_alpha[who2] < 0.0f)
			p_icon_alpha[who2] = 0.0f;
	}

	// If we're dead, reduce the death counter and respawn
	if(!alive) {
		death_counter--;
		if(death_counter == 0) {
			// Respawn to a block
			int ox, oy;
			get_respawn_position((int)get_real_x(), (int)get_real_y(), ox, oy);

			int odir = dir;
			//clear();
			alive = true;
			x = ox;
			y = oy;
			dir = odir;
			nextdir = dir;
			tx = x;
			ty = y;
			walking = false;
			jumping = false;
			dying = false;
			offset = 0.0f;
			create_teleport_effect(x, y);
			show_icon(who2);

			// Play the appear sound
			play_sound(SND_APPEAR, false);

		}
		return;
	}

	// Advance the dying animation if we're actually dying
	if(dying) {
		die_anim -= 0.03f;

		// Create the blue "burning down" effect
		float px = get_real_x();
		float py = get_real_y();
		for(int f=0; f < RAND(2,10); f++) {
			float rnd = RANDF(-0.3f, 0.3f);
			VECT pos(px, 2*size - 0.05f - (2.5f*size*(1-die_anim)), py);
			pos.x += rnd;
			pos.z -= rnd;
			if(pos.y < 0.0f)
				pos.y = 0.0f;
			VECT dir = 0.0f;
			float c1[4] = { 0.1f, 0.7f, 1, 1 };
			float c2[4] = { 0.1f, 0.7f, 1, 0 };
			add_particle(pos, dir, RAND(20,35), 0.1f, 0.4f, c1, c2, part_star);
		}

		if(die_anim < 0.0f) {
			die_anim = 0.0f;
			alive = false;

			// Explode the player bombs
			if(num_bombs > 0) {
				list<BOMB>::iterator b;
				for(b = bomblist.begin(); b != bomblist.end(); ++b)
					if((*b).owner == who && (*b).time > 1)
						(*b).time = 1;		// Makes the bomb explode on the next cycle
			}
		}

		return;
	}


	// Jumping stuff
	if(jumping) {
		jump_pos += jump_speed;
		if(jump_pos >= 1.0f) {
			jump_pos = 1.0f;

			// We're now on the target tile
			x = jump_tx;
			y = jump_ty;
			tx = x;
			ty = y;
			offset = 0.0f;
			jumping = false;
		}

		// Create some particles if we're teleporting
		if(in_teleport && jumping) {
			VECT pos(get_real_x(), 0.25f, get_real_y());
			pos += jump_dir * jump_pos * jump_dist;
			pos.y += jump_height * SIN(180.0f * jump_pos);

			VECT dir;
			for(int f=0; f<5; f++) {
				VECT ppos = pos + VECT(RANDF(-0.5f,0.5f),RANDF(-0.5f,0.5f),RANDF(-0.5f,0.5f));
				dir.x = dir.y = dir.z = 0.0f;
				float c1[4] = { 0.3, 0.7f, 1, 1 };
				float c2[4] = { 0, 0, 1, 0 };

				add_particle(ppos, dir, RAND(10,30), 0.1f, 0.3f, c1, c2, part_teleport);
			}
		}


		// This is a dirty hack. Read the comments from the beginning of this file.
		if(map[jump_tx][jump_ty][1] && jump_pos > 0.9f) {
			players_on_block_x[who2] = jump_tx;
			players_on_block_y[who2] = jump_ty;
		}

		return;
	}

	// This is a dirty hack. Read the comments from the beginning of this file.
	if(map[x][y][1]) {
		players_on_block_x[who2] = x;
		players_on_block_y[who2] = y;
		//return;
	}
	else {
		players_on_block_x[who2] = -1;
	}

	// Don't move if we're using the napalm or the teleport power
	if(using_special_power && (which_special_power == RED_POWER_NAPALM))
		return;
	if(using_special_power == who && (which_special_power == BLUE_POWER_TELEPORT))
		return;

	// Don't move if the level is finished
	if(level_pause)
		return;


	// Advance the animation
	anim += 0.20f;
	if((int)anim > 3)
		anim = 0.0f;

	// Advance the turning animation
	if(turning) {
		turning_counter++;
		if(turning_counter == 5) {
			dir = nextdir;
			nextdir = dir + 1;
			if(nextdir > DIR_W)
				nextdir = DIR_N;
		}
		else if(turning_counter == 10) {
			dir = nextdir;
			turning = false;
		}
	}


	if(!walking && ((config.moving_style[who2] == MOV_RELATIVE && !key[config.key_up[who2]]) || (config.moving_style[who2] == MOV_ABSOLUTE && !key[config.key_up[who2]] && !key[config.key_down[who2]] && !key[config.key_left[who2]] && !key[config.key_right[who2]])))
		anim = 0.0f;

	// Check if we're on a block
	bool on_block = false;
	if(map_solid(x,y))
		on_block = true;

	// Don't move if we're using the flower power (absolute)
	if(on_block && config.moving_style[who2] == MOV_ABSOLUTE && (p1.num_flower_bombs > 0 || p2.num_flower_bombs > 0))
		return;


	// Check for turning input
	if(key[config.key_left[who2]]) {
		if(config.moving_style[who2] == MOV_RELATIVE) {
			// Relative moving
			if(!turn_key_down[0] && !turning) {
				// Turn left
				nextdir = dir - 1;
				if(nextdir < DIR_N)
					nextdir = DIR_W;

				if(!walking)
					dir = nextdir;

				turn_key_down[0] = true;
			}
		}
		else if(config.moving_style[who2] == MOV_ABSOLUTE && !walking) {
			// Absolute moving
			dir = DIR_W;
			walking = true;
			offset = 0.0f;

			tx = x - 1;
			ty = y;

			// Check if the target is passable?
			if(map_solid(tx, ty)) {
				tx = x;
				ty = y;
				walking = false;
			}

			if(on_block) {
				// We're on a block, jump down from it
				jump(tx, ty, 2.0f, 0.05f);
				tx = x;
				ty = y;
				anim = 0;
				on_block = true;

				// Play the jumping sound
				if(jumping)
					play_sound(SND_JUMP, false);
			}
		}
	}
	else
		turn_key_down[0] = false;

	if(key[config.key_right[who2]]) {
		if(config.moving_style[who2] == MOV_RELATIVE) {
			// Relative moving
			if(!turn_key_down[1] && !turning) {
				// Turn right
				nextdir = dir + 1;
				if(nextdir > DIR_W)
					nextdir = DIR_N;

				if(!walking)
					dir = nextdir;

				turn_key_down[1] = true;
			}
		}
		else if(config.moving_style[who2] == MOV_ABSOLUTE && !walking) {
			// Absolute moving
			dir = DIR_E;
			walking = true;
			offset = 0.0f;

			tx = x + 1;
			ty = y;

			// Check if the target is passable?
			if(map_solid(tx, ty)) {
				tx = x;
				ty = y;
				walking = false;
			}

			if(on_block) {
				// We're on a block, jump down from it
				jump(tx, ty, 2.0f, 0.05f);
				tx = x;
				ty = y;
				anim = 0;
				on_block = true;

				// Play the jumping sound
				if(jumping)
					play_sound(SND_JUMP, false);
			}
		}
	}
	else
		turn_key_down[1] = false;

	// Check for 180 degree turning
	if(key[config.key_down[who2]]) {
		if(config.moving_style[who2] == MOV_RELATIVE) {
			// Relative moving
			if(!turn_key_down[2] && !turning && !walking && !key[config.key_up[who2]]) {
				nextdir = dir + 1;
				if(nextdir > DIR_W)
					nextdir = DIR_N;
				turning = true;
				turning_counter = 0;

				turn_key_down[2] = true;
			}
		}
		else if(config.moving_style[who2] == MOV_ABSOLUTE && !walking) {
			// Absolute moving
			dir = DIR_S;
			walking = true;
			offset = 0.0f;

			tx = x;
			ty = y + 1;

			// Check if the target is passable?
			if(map_solid(tx, ty)) {
				tx = x;
				ty = y;
				walking = false;
			}

			if(on_block) {
				// We're on a block, jump down from it
				jump(tx, ty, 2.0f, 0.05f);
				tx = x;
				ty = y;
				anim = 0;
				on_block = true;

				// Play the jumping sound
				if(jumping)
					play_sound(SND_JUMP, false);
			}
		}
	}
	else
		turn_key_down[2] = false;

	// Don't move if we're using the flower power (relative)
	if(on_block && config.moving_style[who2] == MOV_RELATIVE && (p1.num_flower_bombs > 0 || p2.num_flower_bombs > 0))
		return;

	// Check for walking input
	if(key[config.key_up[who2]] && !walking && !turning) {
		if(config.moving_style[who2] == MOV_RELATIVE) {
			// Relative moving
			walking = true;
			offset = 0.0f;

			dir = nextdir;

			switch(dir) {
				default:
				case DIR_N: tx = x; ty = y - 1; break;
				case DIR_E: tx = x + 1; ty = y; break;
				case DIR_S: tx = x; ty = y + 1; break;
				case DIR_W: tx = x - 1; ty = y; break;
			}

			// Check if the target is passable?
			if(map_solid(tx, ty)) {
				tx = x;
				ty = y;
				walking = false;
			}

			if(on_block) {
				// We're on a block, jump down from it
				jump(tx, ty, 2.0f, 0.05f);
				tx = x;
				ty = y;
				anim = 0;
				on_block = true;

				// Play the jumping sound
				if(jumping)
					play_sound(SND_JUMP, false);
			}
		}
		else {
			// Absolute moving
			dir = DIR_N;
			walking = true;
			offset = 0.0f;

			tx = x;
			ty = y - 1;

			// Check if the target is passable?
			if(map_solid(tx, ty)) {
				tx = x;
				ty = y;
				walking = false;
			}

			if(on_block) {
				// We're on a block, jump down from it
				jump(tx, ty, 2.0f, 0.05f);
				tx = x;
				ty = y;
				anim = 0;
				on_block = true;

				// Play the jumping sound
				if(jumping)
					play_sound(SND_JUMP, false);
			}
		}
	}


	// Move towards the target tile
	if(offset < 1.0f && (tx != x || ty != y)) {
		offset += 0.1f;

		// If we're reached the target tile, move again
		if(offset >= 1.0f) {
			x = tx;
			y = ty;
			offset = 0.0f;
			walking = false;

			in_teleport = 0;
		}
	}

	// Reload the weapons
	if(reload > 0)
		reload--;

	// Dropping bombs
	if(key[config.key_shoot[who2]] && reload == 0 && num_bombs < 3 && !on_block && !icon_menu.wait) {
		reload = 30;

		// Plant the bomb
		add_bomb(x, y, BTYP_NORMAL, who);
		num_bombs++;

		// Play the sound
		play_sound(SND_BOMB, false);
	}


	// Invoke the special powers
	if(key[config.key_special[who2]]) {
		open_icon_menu(who, on_block);
		show_icon(0);
		show_icon(1);
	}

#endif
}
示例#20
0
文件: game.c 项目: noox/Raketka
//funkce obstara efekt pri ztrate zivota (power levelu)
void player_injury(float posx, float posy) {
	int i;
	for (i=0;i<110;i++)
		add_particle(posx, posy, 50*DFRAND, 50*DFRAND, FRAND, 1, FRAND, 0.5, 2);
}
示例#21
0
文件: foe.c 项目: mpersano/protozoa
static void
foe_common_gen_explosion(struct foe_common *f, float scale)
{
	int i;
	particle *p;
	int ndebris, nballs;

	ndebris = scale*(40 + irand(30));

	/* debris */

	for (i = 0; i < ndebris; i++) {
		p = add_particle();

		if (!p)
			break;

		p->ttl = 20 + irand(15);
		p->t = 0;
		p->width = scale*.4f*(.6f + .15f*frand());
		p->height = scale*.3f*(2.8f + .4f*frand());
		p->pos = f->pos;
		p->palette = PAL_YELLOW;
		p->friction = .9;

		vec2_set(&p->dir, frand() - .5f, frand() - .5f);
		vec2_normalize(&p->dir);

		p->speed = scale*(PARTICLE_SPEED + .05f*frand());
	}

#define RADIUS .4f

	/* fireballs */

	nballs = scale*(8 + irand(8));

	for (i = 0; i < nballs; i++) {
		vector2 pos;
		float r, l;
		l = 1.2*scale;
		pos.x = f->pos.x + l*frand() - .5f*l;
		pos.y = f->pos.y + l*frand() - .5f*l;
		r = scale*(.2f + .15f*frand());
		add_explosion(&pos, r, EFF_EXPLOSION, 13 + irand(4));
	}

	/* shockwave */
	add_explosion(&f->pos, scale*.3f, EFF_RING, 18);

/*
	p = add_particle();

	if (p) {
		p->t = 0;
		p->ttl = 20;
		p->width = p->height = scale*.3f;
		p->pos = f->pos;
		p->palette = PAL_RED;
		p->type = PT_SHOCKWAVE;
	}
*/

	perturb_water(&f->pos, scale*1200.f);

	play_fx(FX_EXPLOSION_1);
}
示例#22
0
Node * split (Node *root, Particle *p)
{
  Node * new_node;
  Particle * old_particle;
  double x3 = (root->tl.x + root->br.x) / 2;
  double y3 = (root->tl.y + root->br.y) / 2;
  
  old_particle = root->particle;
  root->particle = NULL;
  root->is_leaf = 0;

  new_node = (Node *) malloc (sizeof (Node));
  new_node->one = new_node->two = new_node->three = new_node->four = NULL;
  new_node->particle = NULL;
  new_node->is_leaf = 1;
  new_node->tl.x= root->tl.x;
  new_node->tl.y= root->tl.y;
  new_node->br.x= x3;
  new_node->br.y= y3;
  new_node->parent = root;
  new_node->total_mass = 0;
  new_node->cm.x = new_node->cm.y = -1.0;
  root->one = new_node;

  new_node = (Node *) malloc (sizeof (Node));
  new_node->one = new_node->two = new_node->three = new_node->four = NULL;
  new_node->particle = NULL;
  new_node->is_leaf = 1;
  new_node->tl.x= x3;
  new_node->tl.y= root->tl.y;
  new_node->br.x= root->br.x;
  new_node->br.y= y3;
  new_node->parent = root;
  new_node->total_mass = 0;
  new_node->cm.x = new_node->cm.y = -1.0;
  root->two = new_node;  
  
  new_node = (Node *) malloc (sizeof (Node));
  new_node->one = new_node->two = new_node->three = new_node->four = NULL;
  new_node->particle = NULL;
  new_node->is_leaf = 1;
  new_node->tl.x= root->tl.x;
  new_node->tl.y= y3;
  new_node->br.x= x3;
  new_node->br.y= root->br.y;
  new_node->parent = root;
  new_node->total_mass = 0;
  new_node->cm.x = new_node->cm.y = -1.0;
  root->three = new_node;  

  new_node = (Node *) malloc (sizeof (Node));
  new_node->one = new_node->two = new_node->three = new_node->four = NULL;
  new_node->particle = NULL;
  new_node->is_leaf = 1;
  new_node->tl.x= x3;
  new_node->tl.y= y3;
  new_node->br.x= root->br.x;
  new_node->br.y= root->br.y;
  new_node->parent = root;
  new_node->total_mass = 0;
  new_node->cm.x = new_node->cm.y = -1.0;
  root->four = new_node;  

  switch (child_alternative (root, old_particle))
    {
    case ONE:
      add_particle (root->one, old_particle);
      break;
    case TWO:
      add_particle (root->two, old_particle);
      break;
    case THREE:
      add_particle (root->three, old_particle);
      break;
    case FOUR:
      add_particle (root->four, old_particle);
      break;
    default:
      printf ("ERROR: Bad number of children\n");
      finalize ();
      exit (1);
    }
  switch (child_alternative (root, p))
    {
    case ONE:
      return root->one ;
    case TWO:
      return root->two ;
    case THREE:
      return root->three ;
    case FOUR:
      return root->four ;
    default:
      return NULL;
    }
}
示例#23
0
// Create an explosion to a tile
void create_explosion(int x, int y, int type) {
	int p;
	if(type == EXP_BOMB_NORMAL) {
		for(p = 0; p < RAND(20,40); p++) {
			// Add the explosion flames
			VECT pos(x + 0.5f, 0.0f, y + 0.5f);
			VECT dir;
			dir.x = RANDF(-0.01f, 0.01f);
			dir.y = RANDF(0.0f, 0.1f);
			dir.z = RANDF(-0.01f, 0.01f);
			float c1[4] = { 1, 0.3f, 0.2f, 1 };
			float c2[4] = { 1, 0, 0, 0 };
			add_particle(pos, dir, RAND(10,60), 0.2f, 0.8f, c1, c2, part_explo);
		}
		for(p = 0; p < RAND(10,30); p++) {
			// Add the sparks
			VECT pos(x + 0.5f, 0.0f, y + 0.5f);
			VECT dir;
			dir.x = RANDF(-0.05f, 0.05f);
			dir.y = RANDF(0.0f, 0.1f);
			dir.z = RANDF(-0.05f, 0.05f);
			float c1[4] = { 1, 0.7f, 0.3f, 1 };
			float c2[4] = { 0, 0, 1, 0 };
			add_particle(pos, dir, RAND(20,70), 0.05f, 0.01f, c1, c2, part_spark);
		}
	}

	if(type == EXP_BOMB_FLOWER) {
		for(p = 0; p < RAND(10,30); p++) {
			// Add the explosion flames
			VECT pos(x + 0.5f, 0.0f, y + 0.5f);
			VECT dir;
			dir.x = RANDF(-0.01f, 0.01f);
			dir.y = RANDF(0.0f, 0.1f);
			dir.z = RANDF(-0.01f, 0.01f);
			float c1[4] = { 0.5f, 0, 1, 1 };
			float c2[4] = { 0.2f, 1, 0.2f, 0 };
			add_particle(pos, dir, RAND(10,60), 0.2f, 0.8f, c1, c2, part_explo);
		}
		for(p = 0; p < RAND(1,5); p++) {
			// Add the flowers
			VECT pos(x + 0.5f, 0.0f, y + 0.5f);
			VECT dir;
			dir.x = RANDF(-0.05f, 0.05f);
			dir.y = RANDF(0.0f, 0.1f);
			dir.z = RANDF(-0.05f, 0.05f);
			float c1[4] = { 1, 1, 1, 1 };
			float c2[4] = { 1, 1, 1, 0 };
			add_particle(pos, dir, RAND(50,100), 0.5f, 0.1f, c1, c2, part_flower, true);
		}
	}

	else if(type == EXP_BOMB_CENTER) {
		for(p = 0; p < RAND(30,70); p++) {
			// Add the explosion flames
			VECT pos(x + 0.5f, 0.0f, y + 0.5f);
			VECT dir;
			dir.x = RANDF(-0.01f, 0.01f);
			dir.y = RANDF(0.0f, 0.1f);
			dir.z = RANDF(-0.01f, 0.01f);
			float c1[4] = { 1, 0.7f, 0.3f, 1 };
			float c2[4] = { 1, 0, 0, 0 };
			add_particle(pos, dir, RAND(10,60), 0.2f, 0.8f, c1, c2, part_explo);
		}
		for(p = 0; p < RAND(10,40); p++) {
			// Add the sparks
			VECT pos(x + 0.5f, 0.0f, y + 0.5f);
			VECT dir;
			dir.x = RANDF(-0.05f, 0.05f);
			dir.y = RANDF(0.0f, 0.1f);
			dir.z = RANDF(-0.05f, 0.05f);
			float c1[4] = { 1, 0.7f, 0.3f, 1 };
			float c2[4] = { 0, 0, 1, 0 };
			add_particle(pos, dir, RAND(20,70), 0.05f, 0.01f, c1, c2, part_spark);
		}
	}

	else if(type == EXP_BOMB_CENTER_FLOWER) {
		for(p = 0; p < RAND(20,30); p++) {
			// Add the explosion flames
			VECT pos(x + 0.5f, 0.0f, y + 0.5f);
			VECT dir;
			dir.x = RANDF(-0.01f, 0.01f);
			dir.y = RANDF(0.0f, 0.1f);
			dir.z = RANDF(-0.01f, 0.01f);
			float c1[4] = { 0.3f, 1, 0.3f, 1 };
			float c2[4] = { .5f, 0, 1, 0 };
			add_particle(pos, dir, RAND(10,60), 0.2f, 0.8f, c1, c2, part_explo);
		}
		for(p = 0; p < RAND(1,5); p++) {
			// Add the flowers
			VECT pos(x + 0.5f, 0.0f, y + 0.5f);
			VECT dir;
			dir.x = RANDF(-0.05f, 0.05f);
			dir.y = RANDF(0.0f, 0.1f);
			dir.z = RANDF(-0.05f, 0.05f);
			float c1[4] = { 1, 1, 1, 1 };
			float c2[4] = { 1, 1, 1, 0 };
			add_particle(pos, dir, RAND(50,100), 0.5f, 0.1f, c1, c2, part_flower, true);
		}
	}

	else if(type == EXP_NAPALM) {
		for(p = 0; p < RAND(20,50); p++) {
			// Add the explosion flames
			VECT pos(x + 0.5f, 0.0f, y + 0.5f);
			VECT dir;
			dir.x = RANDF(-0.01f, 0.01f);
			dir.y = RANDF(0.0f, 0.1f);
			dir.z = RANDF(-0.01f, 0.01f);
			float c1[4] = { 1, 0.3f, 0.2f, 1 };
			float c2[4] = { 1, 0, 0, 0 };
			add_particle(pos, dir, RAND(10,60), 0.2f, 0.8f, c1, c2, part_explo);
		}
		for(p = 0; p < RAND(10,30); p++) {
			// Add the sparks
			VECT pos(x + 0.5f, 0.0f, y + 0.5f);
			VECT dir;
			dir.x = RANDF(-0.05f, 0.05f);
			dir.y = RANDF(0.0f, 0.1f);
			dir.z = RANDF(-0.05f, 0.05f);
			float c1[4] = { 1, 0.7f, 0.3f, 1 };
			float c2[4] = { 0, 0, 1, 0 };
			add_particle(pos, dir, RAND(20,70), 0.05f, 0.01f, c1, c2, part_spark);
		}
	}
}
示例#24
0
void process_message_from_server(unsigned char *in_data, int data_lenght)
{
	//see what kind of data we got
	switch (in_data[PROTOCOL])
		{
		case RAW_TEXT:
			{
				// do filtering and ignoring
				data_lenght=filter_or_ignore_text(&in_data[3],data_lenght-3)+3;
				if(data_lenght > 3)
					{
						//how to display it
						if(interface_mode!=interface_opening)
							put_text_in_buffer(&in_data[3],data_lenght-3,0);
						else put_text_in_buffer(&in_data[3],data_lenght-3,54);
						//lets log it
						write_to_log(&in_data[3],data_lenght-3);
					}
			}
			break;
		
		case SMALL_WINDOW_TEXT:
			{
				add_text_to_small_text_buffer(in_data+3, data_lenght-3);
				display_small_text_window();
			}
			break;

		case ADD_NEW_ACTOR:
			{
				add_actor_from_server(&in_data[3]);
			}
			break;

		case ADD_NEW_ENHANCED_ACTOR:
			{
				add_enhanced_actor_from_server(&in_data[3]);
			}
			break;

		case ADD_ACTOR_COMMAND:
			{
				add_command_to_actor(*((short *)(in_data+3)),in_data[5]);
			}
			break;

		case REMOVE_ACTOR:
			{
				destroy_actor(*((short *)(in_data+3)));
			}
			break;

		case KILL_ALL_ACTORS:
			{
				destroy_all_actors();
			}
			break;

		case NEW_MINUTE:
			{
				game_minute=*((short *)(in_data+3));
				new_minute();
			}
			break;

		case LOG_IN_OK:
			{
				interface_mode=interface_game;
				previously_logged_in=1;
			}
			break;

		case HERE_YOUR_STATS:
			{
				get_the_stats((Sint16 *)(in_data+3));
			}
			break;

		case SEND_PARTIAL_STAT:
			{
				get_partial_stat(*((Uint8 *)(in_data+3)),*((Sint32 *)(in_data+4)));
			}
			break;

		case GET_KNOWLEDGE_LIST:
			{
				get_knowledge_list(*(Uint16 *)(in_data+1)-1, in_data+3);
			}
			break;

		case GET_NEW_KNOWLEDGE:
			{
				get_new_knowledge(*(Uint16 *)(in_data+3));
			}
			break;

		case HERE_YOUR_INVENTORY:
			{
				get_your_items(in_data+3);
			}
			break;

		case GET_NEW_INVENTORY_ITEM:
			{
				get_new_inventory_item(in_data+3);
			}
			break;

		case REMOVE_ITEM_FROM_INVENTORY:
			{
				remove_item_from_inventory(*((Uint8 *)(in_data+3)));
			}
			break;

		case INVENTORY_ITEM_TEXT:
			{
				put_small_text_in_box(&in_data[3],data_lenght-3,6*51+100,items_string);
				if(!(get_show_window(items_win)||get_show_window(trade_win)))
					{
						put_text_in_buffer(&in_data[3],data_lenght-3,0);
					}
			}
			break;

		case GET_KNOWLEDGE_TEXT:
			{
				put_small_text_in_box(&in_data[3],data_lenght-3,6*51+150,knowledge_string);
			}
			break;

		case CHANGE_MAP:
			{
				current_sector=-1;
				if(map_file_name[0]!=0)
					save_map(map_file_name);
				object_under_mouse=-1;//to prevent a nasty crash, while looking for bags, when we change the map
				close_dialogue();	// close the dialogue window if open
				destroy_all_particles();

				if(!load_map(&in_data[4])){ // creating map if it does not exist
					int size=(in_data[3]&0x1f)<<4;
					new_map(size,size);
					dungeon=(in_data[3]&0x20)?1:0;
					strcpy(map_file_name,&in_data[4]);
					save_map(map_file_name);
				}
				kill_local_sounds();
#ifndef	NO_MUSIC
				playing_music=0;
#endif	//NO_MUSIC
				get_map_playlist();
				have_a_map=1;
				//also, stop the rain
				seconds_till_rain_starts=-1;
				seconds_till_rain_stops=-1;
				is_raining=0;
				rain_sound=0;//kill local sounds also kills the rain sound
				weather_light_offset=0;
				rain_light_offset=0;
			}
			break;

		case GET_TELEPORTERS_LIST:
			{
				add_teleporters_from_list(&in_data[3]);
			}
			break;

		case PLAY_MUSIC:
			{
				if(!no_sound)play_music(*((short *)(in_data+3)));
			}
			break;

		case PLAY_SOUND:
			{
				if(!no_sound)add_sound_object(*((short *)(in_data+3)),*((short *)(in_data+5)),*((short *)(in_data+7)),*((char *)(in_data+9)),*((short *)(in_data+10)));
			}
			break;

		case TELEPORT_OUT:
			{
				add_particle_sys_at_tile("./particles/teleport_in.part",*((short *)(in_data+3)),*((short *)(in_data+5)));
				if(!no_sound)add_sound_object(snd_tele_out,*((short *)(in_data+3)),*((short *)(in_data+5)),1,0);
			}
			break;

		case TELEPORT_IN:
			{
				add_particle_sys_at_tile("./particles/teleport_in.part",*((short *)(in_data+3)),*((short *)(in_data+5)));
				if(!no_sound)add_sound_object(snd_tele_in,*((short *)(in_data+3)),*((short *)(in_data+5)),1,0);
			}
			break;

		case LOG_IN_NOT_OK:
			{
				sprintf(log_in_error_str,"%s: %s",reg_error_str,invalid_pass);
			}
			break;

		case REDEFINE_YOUR_COLORS:
			{
				strcpy(log_in_error_str,redefine_your_colours);
			}
			break;

		case YOU_DONT_EXIST:
			{
				sprintf(log_in_error_str,"%s: %s",reg_error_str,char_dont_exist);
			}
			break;


		case CREATE_CHAR_NOT_OK:
			{
				sprintf(create_char_error_str,"%s: %s",reg_error_str,char_name_in_use);
				return;
			}
			break;


		case CREATE_CHAR_OK:
			{
				login_from_new_char();
			}
			break;

		case YOU_ARE:
			{
				yourself=*((short *)(in_data+3));
			}
			break;

		case START_RAIN:
			{
				seconds_till_rain_starts=*((Uint8 *)(in_data+3));
				seconds_till_rain_stops=-1;
			}
			break;

		case STOP_RAIN:
			{
				seconds_till_rain_stops=*((Uint8 *)(in_data+3));
				seconds_till_rain_starts=-1;
			}
			break;

		case THUNDER:
			{
				add_thunder(rand()%5,*((Uint8 *)(in_data+3)));
			}
			break;


		case SYNC_CLOCK:
			{
				server_time_stamp=*((int *)(in_data+3));
				client_time_stamp=SDL_GetTicks();
				client_server_delta_time=server_time_stamp-client_time_stamp;
			}
			break;

		case PONG:
			{
				Uint8 str[160];
				sprintf(str,"%s: %i MS",server_latency, SDL_GetTicks()-*((Uint32 *)(in_data+3)));
				log_to_console(c_green1,str);
			}
			break;

		case UPGRADE_NEW_VERSION:
			{
				log_to_console(c_red1,update_your_client);
				log_to_console(c_red1,(char*)web_update_address);
			}
			break;

		case UPGRADE_TOO_OLD:
			{
				log_to_console(c_red1,client_ver_not_supported);
				log_to_console(c_red1,(char*)web_update_address);
				this_version_is_invalid=1;
			}
			break;

		case GET_NEW_BAG:
			{
				put_bag_on_ground(*((Uint16 *)(in_data+3)),*((Uint16 *)(in_data+5)),*((Uint8 *)(in_data+7)));
			}
			break;

		case GET_BAGS_LIST:
			{
				add_bags_from_list(&in_data[3]);
			}
			break;

		case SPAWN_BAG_PARTICLES:
			{
			  add_particle_sys_at_tile("./particles/bag_in.part",*((Uint16 *)(in_data+3)),*((Uint16 *)(in_data+5)));
			}
			break;

		case GET_NEW_GROUND_ITEM:
			{
				get_bag_item(in_data+3);
			}
			break;

		case HERE_YOUR_GROUND_ITEMS:
			{
				get_bags_items_list(&in_data[3]);
			}
			break;

		case CLOSE_BAG:
			{
				hide_window(ground_items_win);
			}
			break;

		case REMOVE_ITEM_FROM_GROUND:
			{
				remove_item_from_ground(in_data[3]);
			}
			break;

		case DESTROY_BAG:
			{
				remove_bag(in_data[3]);
			}
			break;

		case NPC_TEXT:
			{
				put_small_text_in_box(&in_data[3],data_lenght-3,dialogue_menu_x_len-70,dialogue_string);
				display_dialogue();
				if(in_data[3]>=127 && in_data[4]>=127)
					{
						add_questlog(&in_data[4],data_lenght-4);
					}
			}
			break;

		case SEND_NPC_INFO:
			{
				my_strcp(npc_name,&in_data[3]);
				cur_portrait=in_data[23];
			}
			break;

		case NPC_OPTIONS_LIST:
			{
				build_response_entries(&in_data[3],*((Uint16 *)(in_data+1)));
			}
			break;

		case GET_TRADE_ACCEPT:
			{
				if(!in_data[3])trade_you_accepted=1;
				else
					trade_other_accepted=1;
			}
			break;

		case GET_TRADE_REJECT:
			{
				if(!in_data[3])trade_you_accepted=0;
				else
					trade_other_accepted=0;
			}
			break;

		case GET_TRADE_EXIT:
			{
				hide_window(trade_win);
			}
			break;

		case GET_YOUR_TRADEOBJECTS:
			{
				get_your_trade_objects(in_data+3);
			}
			break;

		case GET_TRADE_OBJECT:
			{
				put_item_on_trade(in_data+3);
			}
			break;

		case REMOVE_TRADE_OBJECT:
			{
				remove_item_from_trade(in_data+3);
			}
			break;

		case GET_TRADE_PARTNER_NAME:
			{
				get_trade_partner_name(&in_data[3],*((Uint16 *)(in_data+1))-1);
			}
			break;

		case GET_ACTOR_DAMAGE:
			{
				get_actor_damage(*((Uint16 *)(in_data+3)),in_data[5]);
			}
			break;

		case GET_ACTOR_HEAL:
			{
				get_actor_heal(*((Uint16 *)(in_data+3)),in_data[5]);
			}
			break;

		case ACTOR_UNWEAR_ITEM:
			{
				unwear_item_from_actor(*((Uint16 *)(in_data+3)),in_data[5]);
			}
			break;

		case ACTOR_WEAR_ITEM:
			{
				actor_wear_item(*((Uint16 *)(in_data+3)),in_data[5],in_data[6]);
			}
			break;

		case NPC_SAY_OVERTEXT:
			{
				add_displayed_text_to_actor(
					get_actor_ptr_from_id( *((Uint16 *)(in_data+3)) ), in_data+5 );
			}
			break;

		case BUDDY_EVENT:
			{
				if(in_data[3]==1)
					add_buddy(&in_data[5],in_data[4],data_lenght-5);
				else if(in_data[3]==0)
					del_buddy(&in_data[4],data_lenght-4);
			}
			break;

		// BARREN MOON NEW MESSAGES
		case THIS_IS_ACTIVE_SECTOR:
			active_sector=*((Uint16 *)(in_data+3));
			break;

		case GET_TILE_DATA:
			get_tile_data(in_data+3);
			break;

		case GET_3D_OBJECTS:
			get_3d_objects(in_data+3);
			break;

		case GET_2D_OBJECTS:
			get_2d_objects(in_data+3);
			break;

		case GET_LIGHT_OBJECTS:
			get_light_objects(in_data+3);
			break;

		case GET_PARTICLE_OBJECTS:
			get_particle_objects(in_data+3);
			break;

		case GET_3D_OBJECTS_FULL_ROTATION:
			get_3d_objects_full_rotation(in_data+3);
			break;

		case GET_CHECKSUMS:
		{
			actor *actor=pf_get_our_actor();
			get_checksums(in_data+3, sector_get(actor->x_pos,actor->y_pos));
			break;
		}

		case ADD_3D_OBJECT:
			add_3d_object(in_data+3);
			break;

		case ADD_3D_OBJECT_FULL_ROTATION:
			add_3d_object_fullrotation(in_data+3);
			break;

		case DELETE_3D_OBJECT:
			delete_3d_object(in_data+3);
			break;

		case REPLACE_3D_OBJECT:
			replace_3d_object(in_data+3);
			break;

		case ADD_2D_OBJECT:
			add_2d_object(in_data+3);
			break;

		case DELETE_2D_OBJECT:
			delete_2d_object(in_data+3);
			break;

		case REPLACE_2D_OBJECT:
			replace_2d_object(in_data+3);
			break;

		case ADD_LIGHT:
			add_lights(in_data+3);
			break;

		case DELETE_LIGHT:
			delete_light(in_data+3);
			break;

		case ADD_PARTICLE:
			add_particle(in_data+3);
			break;

		case DELETE_PARTICLE:
			delete_particle(in_data+3);
			break;

		case REPLACE_PARTICLE:
			replace_particle(in_data+3);
			break;

		default:
			{
				/* Unknown data type?? */;
			}
			break;
		}
}
int main(void) {
  t_gravity_particles gravity_particles;
  t_particle_system* particle_system;
  t_particle* p;
  int i;
  
  show_msgbox(
    "Ndless - Particle System Demo",
    "------------------------\n"
    "       Particle System Demo\n" \
    "© 2010-2011 by the Ndless Team\n"
    "------------------------\n"
    "+  Add a particle\n"
    "-  Remove a particle\n"
    "*  Increase gravity\n"
    "/  Decrease gravity\n"
    "C  Enable/Disable collision detection\n"
    "T  Enable/Disable trace mode\n"
    "S  Clear screen\n"
    "ESC - Exit"
  );

	if (is_classic) { // programs are started with the screen cleared on non-classic
		void *scrbuf = malloc(SCREEN_BYTES_SIZE);
		memcpy(scrbuf, SCREEN_BASE_ADDRESS, SCREEN_BYTES_SIZE);
	  for (i = 0; i < 0x0F; ++i) {
	    fade(scrbuf, 1);
	    sleep(70);
	    if (isKeyPressed(KEY_NSPIRE_ESC)) {
	    	free(scrbuf);
	    	return 0;
	    }
	  }
	  free(scrbuf);
	}
	
	clrscr();
	lcd_ingray();

  gravity_particles_construct(&gravity_particles, 0.00006672f, 100);
  particle_system = &(gravity_particles.particleSystem);
  particle_system->detectCol = false;
  particle_system->trace = false;
  particle_system_start(particle_system);

  p = particle_construct3(&(t_vector){0.f, 0.f, 0.f}, &(t_vector){0.f, 0.f, 0.f}, 1500.f, 4, BLACK);
  (void) particle_system_addParticle(particle_system, p);
  add_particle(&gravity_particles);

  while (!isKeyPressed(KEY_NSPIRE_ESC)) {
    gravity_particles_draw(&gravity_particles);

    // Add a particule (+)
    if (isKeyPressed(KEY_NSPIRE_PLUS)) {
      if (particle_system->nParticles == 0) {
        p = particle_construct3(&(t_vector){0.f, 0.f, 0.f}, &(t_vector){0.f, 0.f, 0.f}, 1500.f, 4, BLACK);
        (void) particle_system_addParticle(particle_system, p);
      }
      add_particle(&gravity_particles);
      while (isKeyPressed(KEY_NSPIRE_PLUS));
    }

    // Remove a particle (-)
    if (isKeyPressed(KEY_NSPIRE_MINUS)) {
      remove_particle(&gravity_particles);
      while (isKeyPressed(KEY_NSPIRE_MINUS));
    }

    // High gravity (*)
    if (isKeyPressed(KEY_NSPIRE_MULTIPLY)) {
      gravity_particles.gravitationalConstant *= 10.f;
      while (isKeyPressed(KEY_NSPIRE_MULTIPLY));
    }

    // Low gravity (/)
    if (isKeyPressed(KEY_NSPIRE_DIVIDE)) {
      gravity_particles.gravitationalConstant /= 10.f;
      while (isKeyPressed(KEY_NSPIRE_DIVIDE));
    }

    // Collision (C)
    if (isKeyPressed(KEY_NSPIRE_C)) {
      particle_system->detectCol = !particle_system->detectCol;
      while (isKeyPressed(KEY_NSPIRE_C));
    }

    // Collision (T)
    if (isKeyPressed(KEY_NSPIRE_T)) {
      particle_system->trace = !particle_system->trace;
      while (isKeyPressed(KEY_NSPIRE_T));
    }

    // Collision (S)
    if (isKeyPressed(KEY_NSPIRE_S)) {
      clearScreen();
      while (isKeyPressed(KEY_NSPIRE_S));
    }
  }

  gravity_particles_destruct(&gravity_particles);

  return 0;
}