Ejemplo n.º 1
0
int main(void) {
    World *w = new_world("Adventure In C");
    struct room *current = cached_read_room(w, "start");

    struct player me;
    initPlayer(&me, w);
    read_player(&me);
    push_alias(&me, "l", "look");
    push_alias(&me, "u", "up");
    push_alias(&me, "d", "down");
    push_alias(&me, "lo", "look");  // Just an extra alias
    push_alias(&me, "h", "help");
    push_alias(&me, "ex", "examine");

    me.currentRoom = current;
    printf("%s enters the world.\n\n",me.name);
    look_player(&me);
    loop_player(&me);
}
Ejemplo n.º 2
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;
		}
	}

}
Ejemplo n.º 3
0
struct commandResult execute_command(struct player * me, char * cmd_buffer, char * cmd_param) {
    World *w = me->world;
    struct commandResult result;
    int ret = 0;
    int moved = 0;

    if(strlen(cmd_buffer) == 0) {
        printf("What?\n");
    }
    else if(has_exit(me->currentRoom, cmd_buffer)) {
        printf("You go: %s\n", cmd_buffer);
        char room_file[30];
        memset(&room_file, '\0', sizeof(char)*30);
        get_exit(&room_file, me->currentRoom, cmd_buffer);
        //free currentRoom..

        struct room * nextRoom = cached_read_room(w, room_file);
        if(nextRoom != NULL) {
            // Also free links, items etc
            //free(me->currentRoom);
            me->currentRoom=NULL;
            me->currentRoom = nextRoom;
            moved = 1;
        } else {
            printf("You didn't move.\n");
        }
    }
    else if(strcmp(cmd_buffer, "examine") == 0) {
      if((me->currentRoom)->items == NULL) {
        printf("You do not notice anything.\n");
      } else {
        printf("You notice:-\n");
        struct item * itemPtr = (me->currentRoom)->items;
          do {
            printf("%s\n", itemPtr->name);
            itemPtr = itemPtr->link;
          } while(itemPtr != NULL);
      }
    }
    else if(strcmp(cmd_buffer, "look") == 0) {
        if(cmd_param != NULL && strlen(cmd_param) > 0) {
    //      printf("%s\n", cmd_param);
            if(strcmp(cmd_param, "me") == 0) {
                time_t now;
                time(&now);
                int seconds = (int)difftime(now, me->connectionTime);

                printf(
"================================================================================\n"
"Player: %s\n"
"================================================================================\n"
"Current room: %s\n"
"Connected for: %d seconds\n",
                me->name, (me->currentRoom)->name, seconds);
            } else {
                printf("You do not notice anything special about: '%s'.\n", cmd_param);
            }
        }
        else {
            look_player(me);
        }
    }
    else if(strcmp(cmd_buffer, "mem") == 0) {
      printf("World: %s\n\n", w->name);
      LoadedRoom *head = w->rooms;
      printf("Loaded rooms:\n");
      do {
        printf("- %s\n", (head->current)->fileName);
        head = head->next;
      } while(head != NULL);
        // && head->next!=NULL);

    }
    else if(strcmp(cmd_buffer, "help") == 0) {
        showHelp();
    }
    else if(strcmp(cmd_buffer, "quit")==0) {
        ret = 1;
    }
    else {
        char expanded[30];
        if(find_alias(&expanded, cmd_buffer, me)) {
            printf("Using alias %s.\n", expanded);
            struct commandResult childResult = execute_command(me, &expanded, cmd_param);
            ret = childResult.exit;
            moved = childResult.moved;

        } else {
            printf("I do not understand: '%s'.. ?\n", cmd_buffer);
        }
    }
    result.exit = ret;
    result.moved = moved;
    return result;
}