Exemplo n.º 1
0
void parse_partymsg(char *msg)
{
	char *prefix = strtok_r(NULL, "|", &msg);
	prefix = strtok_r(NULL, "|", &msg);

	// it's a chat message to this party only
	if (strcmp(prefix, CHATMSG_PREFIX) == 0)	
		{
			char *nick = strtok_r(NULL, "|", &msg);
			wattron(log_win, A_BOLD);
			char buf[20] = "(party) ";
			strncat(buf, nick, NAME_MAX_LENGTH);
			ncurs_log_chatmsg(msg, buf);
			wattroff(log_win, A_BOLD);
		}
	if (strcmp(prefix, CTRLMSG_PREFIX) == 0)
		{
		char *ctrlprefix = strtok_r(NULL, "|", &msg);

		// a party member has committed turn in combat
		if (strcmp(ctrlprefix, TURNREADY) == 0)
			{
				// who committed the turn
				char *nick = strtok_r(NULL, "|", &msg);	
				// what skill used
				char *skill = strtok_r(NULL, "|", &msg);
				// what target chosen
				char *target = strtok_r(NULL, "|", &msg);

				// set player_party.characters[i].turnready to chosen skill AND combattarget to chosen target
				for (int i = 0; i <= 2; i++)
					if (strcmp(nick, player_party.characters[i]->name) == 0)
						{
						player_party.characters[i]->turnready = atoi(skill);
						player_party.characters[i]->combattarget = atoi(target);
						// display info about the committed turn
						ncurs_log_sysmsg("Player %s committed turn", nick);
						ncurs_fightinfo(player_party.characters[i], i);
						break;
						}
				// TODO: does this make sense?			
		                // if in combat, calculate combat stuff
		                if (player.incombat)
		                        combat_seeifready();

			}
		// when a player has ran from a fight
		if (strcmp(ctrlprefix, RUNMSG) == 0)
			{
			char *nick = strtok_r(NULL, "|", &msg);	
			// only care about this if you are in combat
			if (player.incombat)
				combat_plr_ran(nick);
			}
		
		}

}
Exemplo n.º 2
0
void skill_effect(Character *source, Character *dest, Skills *skill)
{
	ncurs_log_sysmsg("%s used %s on %s",source->name, skill->name, dest->name);
	int dmg = 0;
	/* calculate normal damage done based on skill + weapon */
	dmg += skill->damage;
	dmg += source->weapon->damage;

	/* if the skill type matches the element in the wu xing day cycle, apply bonus damage */
	if (check_wuxing_time(skill->dmg_type))
		{
		ncurs_log_sysmsg(_("%s is in sync with the element cycle and deals bonus damage!"),source->name);
		dmg += skill->damage / 2; // TODO: balance the effect
		}

	/* calculate blocking by enemy*/
	/* blocking elements are based on skill used to attack. TODO: should this be weapon instead? */
	dmg -= dmg_calc_blocking(dest, skill->dmg_type);

	/* calculate damage */
	if (dmg > 0)
	{
		dest->health -= dmg;
		ncurs_log_sysmsg(_("%s did %d damage to %s"), source->name, dmg, dest->name);

		/* ONLY ALIGN ELEMENTS IF DAMAGE WAS DONE */
		/* elements align == player skill type and weapon type are the same */
		/* also, if elements align, changes to enemy elemental balance occur */
		if (skill->dmg_type == source->weapon->dmg_type) {
			ncurs_log_sysmsg(_("%s causes elemental damage to %s"), source->name, dest->name);
			dmg += source->elements[skill->dmg_type];
			align_elements(dest, skill->dmg_type); // TODO is this correct?
		}
	}
	else
	{ /* don't do negative damage */
		ncurs_log_sysmsg(_("%s blocked attack from %s."), dest->name, source->name);
	}
	source->stamina -= skill->ap_cost; /* spend action points on the attack */
}
Exemplo n.º 3
0
void parse_ctrlmsg(char *msg)
{
	char *prefix = strtok_r(NULL, "|", &msg);
	prefix = strtok_r(NULL, "|", &msg);

	if (strcmp(prefix, FIGHTMSG) == 0)
		{
		// set random seed and fight
		char *seed = strtok_r(NULL, "|", &msg);
		randomseed = atoi(seed);
		srand(randomseed);
		ac_fightscreen();
		}

	if (strcmp(prefix, JOINMSG) == 0) {
		char *joining_plr = strtok_r(NULL, "|", &msg);
		
		// don't show join msg when you're joining
		if (strcmp(joining_plr, player.name) != 0)
		{
			if (is_partymember(joining_plr))
				ncurs_log_sysmsg(_("Partymember %s has entered the realm"), joining_plr);
			else
				ncurs_log_sysmsg(_("%s has entered the realm"), joining_plr);
		}
	}

	if (strcmp(prefix, QUITMSG) == 0) {
		char *leaving_plr = strtok_r(NULL, "|", &msg);
		// player quits after sending this msg, so it will never be echoed back to the quitting player
		if (is_partymember(leaving_plr))
			ncurs_log_sysmsg(_("Partymember %s has left the realm"), leaving_plr);
		else
			ncurs_log_sysmsg(_("%s has left the realm"), leaving_plr);
	}
}
Exemplo n.º 4
0
void use_skill(int keypress)
{
	/* this function is entered with a keypress from ac_fight0 and so on*/
	/* the keypress is used to determine what attack is used */

	/* 1. the player already chose the attack (int keypress), now it's time for the enemy */
	// TODO enemy always uses skill 0

	/* 2. calculate damage */
	/* player does damage */
	/* Wu Xing cycles:
	   Wood causes +FIRE, -EARTH
	   Fire causes +EARTH, -METAL
	   Earth causes +METAL, -WATER
	   Metal causes +WATER, -WOOD
	   Water causes +WOOD, -FIRE
	   */

	if (keypress <= 4 && strcmp(player.skill[keypress]->name,"Unused") != 0)
	{
		// Player attacks
		skill_effect(&player, &enemy, player.skill[keypress]);
		// Enemy attack
		skill_effect(&enemy, &player, enemy.skill[0]);

		/* 3. check for dead player/enemy */
		int enemy_dead = fight_check_dead();

		/* 4. update stats and display them IF THE ENEMY DIDN'T DIE */
		if (!enemy_dead) {
			ncurs_fightinfo(&player, 0);
			ncurs_fightinfo(&enemy, 3);
		}
		wrefresh(game_win);
	}
	else
	{
		ncurs_log_sysmsg(_("You dont have a skill in slot %d"), keypress+1);
	}
}
Exemplo n.º 5
0
void ncurs_chat() 
{
/* TODO: figure out this toggle mess */

	toggle_chat += 1;
	if (toggle_chat >= 3) /* never loop messageboard */
		toggle_chat = 0;

	/* redraw the input line - chat toggle*/
	ncurs_bold_input(toggle_chat);

	char *line = NULL;
	size_t len = 0;
	if (toggle_chat != 0) 
	{
		if (todd_getline(&line, &len, input_win))
		{
			Message msg = create_chat_msg(line, len);
			/* a chat message was succesfully input(ted) */
			if (toggle_chat == 1)
			{
				// party message
				msg = wrap_as_partymsg(msg);
			}
			if (!send_msg(msg))
			{
				ncurs_log_sysmsg(_("Message send failure"));
			}
			del_msg(msg);
		}

		// return to basic input prompt -> press any key for game commands
		// this is done here because if todd_getline returns 0 it means there's an empty line 
		// TODO.. or todd_getline has an error...
		toggle_chat = 0;
		ncurs_bold_input(0); 
		free(line);
	}
}
Exemplo n.º 6
0
void combat_plr_ran(char *nick)
{
// find out which screen to delete from fight window - naturally only affects multiplayer

// do nothing if the running player is you
if (strcmp(nick, player.name) == 0)
	return;

ncurs_log_sysmsg(_("%s ran from a fight. What a coward!"),nick);
int index;
for (index = 0; index <=2; index++)
        if (strcmp(player_party.characters[index]->name, nick) == 0)
                break;

wclear(fight_stat_win[index]);
wrefresh(fight_stat_win[index]);

// set the incombat to false
for (int i = 0; i <= 2; i++)
	if (player_party.characters[i]->name != NULL)
		if (strcmp(player_party.characters[i]->name,nick) == 0)
			player_party.characters[i]->incombat = 0;

}
Exemplo n.º 7
0
void combat_seeifready()
{
// loop through all the players in combat
int allready = 1;


//if (is_online(partymember1.id) || is_online(partymember2.id))	// it's multiplayer combat
if (combat_ismulti())	// it's multiplayer combat
	{
	// loop through all the effects of all party members taking part in the fight
	for (int i = 0; i <= 2; i++)
		if (player_party.characters[i]->incombat)
			{
			if (player_party.characters[i]->turnready < 0)
				{
				ncurs_log_sysmsg("still waiting for: %s",player_party.characters[i]->name);
				allready = 0;	// still waiting for a keypress
				}
			}
	}
else	// it's single player combat
	{
	allready = 1;
	}

// COMBAT EFFECTS START HERE
if (allready) // if everyone is ready, do combat stuff
	{
	ncurs_log_sysmsg(_("all players have committed turns, calculating effects"));
	ncurs_log_sysmsg(_("Combat resolution============================"));
	// combat stuff begins here

	// players attack enemies
	for (int i = 0; i <= 2; i++)
		if (player_party.characters[i]->incombat)
			skill_effect(player_party.characters[i], enemy_party.characters[player_party.characters[i]->combattarget],player_party.characters[i]->skill[player_party.characters[i]->turnready]);

	// enemies attack players
	// choose which player to attack
	int dest = 0;
	int players = 0;
	for (int i = 0; i <= 2; i++)
		if (player_party.characters[i]->incombat)
			players++;
	// players now holds the number of players in combat, randomize one of them
	int i = 0;

	// enemies attack here
	for (int j = 0; j <= 2; j++)
	{
		if (enemy_party.characters[j]->incombat)	// only enemies who are in combat attack
		{
			while (i == 0)	// loop until you find an acceptable target, then attack
			{		
				dest = rand() % players;
				// dest holds a number from 0..players in combat
				if (player_party.characters[dest]->incombat) // this player is in combat -> acceptable target
					i = 1;
			}

			// TODO: random enemy skill (enemies should have more than one skill..
			skill_effect(enemy_party.characters[j], player_party.characters[dest], enemy_party.characters[j]->skill[0]);
		}
	}


	ncurs_log_sysmsg(_("============================================="));
	// combat stuff ends here

	// reset turnready
	for (int i = 0; i <= 2; i++)
		if (player_party.characters[i]->incombat)
			player_party.characters[i]->turnready = -1;	

	/* 3. check for dead player/enemy */
	int all_enemies_dead = fight_check_dead();
	/* 4. update stats and display them IF THE ENEMY DIDN'T DIE */
	if (!all_enemies_dead)
		ac_update_fightscreen();
	else
		{
		ncurs_clear_fightwindows();
		ncurs_modal_msg(_("All enemies are slain! The battle is over"));
		// ac_dungeons makes the player go up a dungeon level
		// -> to stay at the same level, decrease the level here
		player.dungeon_lvl--;
		ac_dungeons();
		}
	}
}
Exemplo n.º 8
0
void use_skill(int keypress)
{
	player.turnready = -1; // when set to [0..3] it means a skill is used this turn
	/* this function is entered with a keypress from ac_fight0 and so on*/
	/* the keypress is used to determine what attack is used */

	/* 1. the player already chose the attack (int keypress), now it's time for the enemy */
	// TODO enemy always uses skill 0

	/* 2. calculate damage */
	/* player does damage */
	/* Wu Xing cycles:
	   Wood causes +FIRE, -EARTH
	   Fire causes +EARTH, -METAL
	   Earth causes +METAL, -WATER
	   Metal causes +WATER, -WOOD
	   Water causes +WOOD, -FIRE
	   */

	// TODO: !succesful_target, return loop here?
	if (keypress <= 4 && strcmp(player.skill[keypress]->name,"Unused") != 0)
	{
		int enemynr = 0;
		for (int i = 0; i <=2; i++)
	        if (enemy_party.characters[i]->incombat)
	                enemynr++;

		// only target if there's more than 1 enemy - enemynr tells us how many we have
		int succesful_target = -1;
		player.combattarget = 0; // reset the target int, by default attack 0
		if (enemynr > 1)
			{
			// Target the attack if it can be targeted
			if (is_targetable(player.skill[keypress]))
				succesful_target = target_attack(player.skill[keypress]);

			if (succesful_target == -1)
				return; // go back to select a different skill? TODO: How?			

			//// end targeting
			// succesful_target now holds the enemy id - store it to your char array
			player.combattarget = succesful_target;
			}
		else // only one enemy, select that one (might be index 0,1 or 2
			{
			for (int i = 0; i <=2; i++)
			        if (enemy_party.characters[i]->incombat)
					{
					player.combattarget = i;
					break;
					}
			}


		// Players attack
		// wait for everyone in the game to commit the skill
	
		// go through all online players. Once a player commits a turn,
		// a TURNREADY is sent
		player.turnready = keypress;
		// if a multiplayer game, go through send_turnready, otherwise directly to combat
		// TODO: will hang if a party member joins game during combat - check for incombat instead of is_online
	//	if (is_online(partymember1.id) || is_online(partymember2.id))
		if (combat_ismulti())
			send_turnready();
		else
			combat_seeifready();
	}
	else
	{
		ncurs_log_sysmsg(_("You dont have a skill in slot %d"), keypress+1);
	}
}
Exemplo n.º 9
0
int fight_check_dead()
{
	/* TODO: figure out the order of checking deaths: attacks are simultaneous. Iniative? */
	// TODO enemy and player codes are almost identical, refactor into a function
	// bool check_chr_dead(Character *chr); or something

	bool enemy_dead;
	bool enemy_dead_elements;
	// loop through all enemies in combat

	for (int i = 0; i <= 2; i++)
		{
		enemy_dead = false;
		enemy_dead_elements = false;

			if (enemy_party.characters[i]->incombat)
				{
					/* check if enemy dies */
					for (size_t j = 0; j < ELEM_COUNT; j++)
						{
							if (enemy_party.characters[i]->elements[j] <= 0) 
							{
								enemy_dead = true;
								enemy_dead_elements = true;
							}
						}
					if (enemy_party.characters[i]->health <= 0)
						enemy_dead = true;
			
				// the current enemy is dead (characters[i])
				if (enemy_dead)	
					{
						enemy_party.characters[i]->incombat = false;
						// TODO: would it look better to display "DEAD" instead of erasing the box?
						werase(fight_stat_win[3+i]);
						wrefresh(fight_stat_win[3+i]);

						int money = 7;
						player.money += money;
				
						if (enemy_dead_elements)
							ncurs_log_sysmsg(_("%s has caused an elemental imbalance in %s"), player.name, enemy_party.characters[i]->name);
					
						ncurs_log_sysmsg(_("%s has killed %s!"), player.name, enemy_party.characters[i]->name);
						// TODO: share money from a kill someway
						ncurs_log_sysmsg(_("%s found %d coins from the body"), player.name, money);

					// if there's no more enemies left, return to dungeons. 
					int alldead = 1;
 					for (int i = 0; i <= 2; i++)
						if (enemy_party.characters[i]->incombat)
 							alldead = 0;

					// if all enemies are dead, the battle is over
					if (alldead)
						{
						player.incombat = false; // don't return to combat any more
						ncurs_log_sysmsg(_("All enemies are slain! The battle is over"));
						return 1;					
						}
					// If there's enemies left, the battle continues (i.e. do nothing)
					}
				}
			}

	/* check if player dies as well */
	// TODO: loop through all players, not just yourself
	bool player_dead = false;
	bool player_dead_elements = false;
	for (size_t i = 0; i < 5; i++)
	{
		if (player.elements[i] <= 0) {
			player_dead = true;
			player_dead_elements = true;
		}
	}
	if (player.health <= 0)
		player_dead = true;

	if (player_dead)
	{
		wclear (game_win);
		if (player_dead_elements) // elements below 0, don't die but faint only
		{
			db_player_location(LOC_FAINTED);
			// TODO: which enemy..
			ncurs_log_sysmsg(_("%s has caused an elemental imbalance in %s"), enemy_party.characters[0]->name, player.name);
			mvwprintw(game_win, 6, 0, _("The world around you starts to spin.\nYou sense a great imbalance inside you."));

			wattron(game_win, A_BOLD);
			wattron(game_win, A_UNDERLINE);
			mvwprintw(game_win, 8, 0, _("You faint. TODO: \"come back in 8 hours??\""));
			wattroff(game_win, A_BOLD);
			wattroff(game_win, A_UNDERLINE);
		}
		else // PERMADEATH
		{
			/* first, set the player location to "DEAD" */
			db_player_location(LOC_DEAD);
			// TODO: which enemy
			ncurs_log_sysmsg(_("%s has killed %s!"), enemy_party.characters[0]->name, player.name);
			mvwprintw(game_win, 6, 0, _("The world fades around you as you fall to the ground, \nbleeding."));
			wattron(game_win, A_BOLD);
			wattron(game_win, A_UNDERLINE);
			mvwprintw(game_win, 8, 0, _("You are dead."));
			wattroff(game_win, A_BOLD);
			wattroff(game_win, A_UNDERLINE);
		}

		// common stuff to death // elemental imbalance
		wrefresh(game_win);
		todd_getchar(NULL);
		playing = false;
	}

	if (enemy_dead || player_dead)
		return 1; /* if enemy / player is dead, don't redraw combat stuff anymore */
	else
		return 0; // redraw combat stuff
}
Exemplo n.º 10
0
int fight_check_dead()
{
	/* TODO: figure out the order of checking deaths: attacks are simultaneous. Iniative? */
	// TODO enemy and player codes are almost identical, refactor into a function
	// bool check_chr_dead(Character *chr); or something

	/* check if enemy dies */
	bool enemy_dead = false;
	bool enemy_dead_elements = false;
	for (size_t i = 0; i < ELEM_COUNT; i++)
	{
		if (enemy.elements[i] <= 0) {
			enemy_dead = true;
			enemy_dead_elements = true;
		}
	}
	if (enemy.health <= 0)
		enemy_dead = true;
	if (enemy_dead)
	{
		int money = 7;
		int exp = 10;
		player.money += money;
		player.experience += exp;
		werase(game_win);
		if (enemy_dead_elements)
			ncurs_log_sysmsg(_("%s has caused an elemental imbalance in %s"), player.name, enemy.name);
		ncurs_log_sysmsg(_("%s has killed %s!"), player.name, enemy.name);
		ncurs_log_sysmsg(_("%s received %d coins and %d XP"), player.name, money, exp);
		ncurs_modal_msg(
				_("%s is slain!\n\nYou find %d coins on the corpse, and gain %d experience\n"),
				enemy.name, money, exp);
		ac_dungeons();
	}

	/* check if player dies as well */
	bool player_dead = false;
	bool player_dead_elements = false;
	for (size_t i = 0; i < 5; i++)
	{
		if (player.elements[i] <= 0) {
			player_dead = true;
			player_dead_elements = true;
		}
	}
	if (player.health <= 0)
		player_dead = true;

	if (player_dead)
	{
	
		wclear (game_win);

		if (player_dead_elements) // elements below 0, don't die but faint only
		{
			db_player_location(LOC_FAINTED);
			ncurs_log_sysmsg(_("%s has caused an elemental imbalance in %s"), enemy.name, player.name);
			mvwprintw(game_win, 6, 0, _("The world around you starts to spin.\nYou sense a great imbalance inside you."));

			wattron(game_win, A_BOLD);
			wattron(game_win, A_UNDERLINE);
			mvwprintw(game_win, 8, 0, _("You faint. TODO: \"come back in 8 hours??\""));
			wattroff(game_win, A_BOLD);
			wattroff(game_win, A_UNDERLINE);
		}
		else // PERMADEATH
		{
			/* first, set the player location to "DEAD" */
			db_player_location(LOC_DEAD);
		
			ncurs_log_sysmsg(_("%s has killed %s!"), enemy.name, player.name);
			mvwprintw(game_win, 6, 0, _("The world fades around you as you fall to the ground, \nbleeding."));
			wattron(game_win, A_BOLD);
			wattron(game_win, A_UNDERLINE);
			mvwprintw(game_win, 8, 0, _("You are dead."));
			wattroff(game_win, A_BOLD);
			wattroff(game_win, A_UNDERLINE);
		}

		// common stuff to death // elemental imbalance
		wrefresh(game_win);
		todd_getchar(NULL);
		playing = false;
	}

	if (enemy_dead || player_dead)
		return 1; /* if enemy / player is dead, don't redraw combat stuff anymore */
	else
		return 0; // redraw combat stuff
}