/*
* itcombat.c Routines to handle inter-terminal combat
*/
#include "include.h"
/***************************************************************************
/ FUNCTION NAME: Do_opponent_struct(struct client_t *c, struct opponent_t *theOpponent)
/
/ FUNCTION: Check to see if a player entered an occupied square
/
/ AUTHOR: Brian Kelly, 8/16/99
/
/ ARGUMENTS:
/ struct server_t s - the server strcture
/ struct game_t this_game - pointer to the player we're checking
/
/ RETURN VALUE: none
/
/ DESCRIPTION:
/ Process arguments, initialize program, and loop forever processing
/ player input.
/
****************************************************************************/
void Do_opponent_struct(struct client_t *c, struct opponent_t *theOpponent)
{
char string_buffer[SZ_LINE];
c->battle.ring_in_use = FALSE;
c->battle.melee_damage = 0.0;
c->battle.skirmish_damage = 0.0;
c->battle.tried_luckout = FALSE;
strcpy(theOpponent->name, c->modifiedName);
theOpponent->processID = c->game->clientPid;
/* passable experience = all player exp now that nicking is capped */
/* Kings and higher are immune to nicking */
if (c->player.special_type >= SC_KING) {
theOpponent->experience = 0.0;
}
else {
theOpponent->experience = floor(c->player.experience /
(30 * c->player.level + 1));
}
theOpponent->strength = c->player.strength + c->player.sword;
theOpponent->max_strength = theOpponent->strength;
theOpponent->energy = c->player.energy;
theOpponent->max_energy = c->player.max_energy + c->player.shield;
theOpponent->speed = c->player.quickness + 1;
theOpponent->max_speed = theOpponent->speed;
theOpponent->brains = c->player.brains;
theOpponent->size = c->player.level;
/* the bigger they are, the harder they fall to all or nothing */
theOpponent->sin = c->player.sin + floor(c->player.level / 100);
sprintf(string_buffer,
"%s, %s, Level %.0lf, Sin %.0f has effective Sin of %.0lf\n",
c->player.lcname,
c->realm->charstats[c->player.type].class_name,
c->player.level,
c->player.sin,
theOpponent->sin);
Do_log(COMBAT_LOG, string_buffer);
theOpponent->shield = 0;
theOpponent->special_type = SM_IT_COMBAT;
theOpponent->treasure_type = 0;
theOpponent->flock_percent = 0;
/* throw up spells for combat */
Do_starting_spells(c);
}
/***************************************************************************
/ FUNCTION NAME: Do_setup_it_combat(struct client_t *c, struct game_t *theGame)
/
/ FUNCTION: Check to see if a player entered an occupied square
/
/ AUTHOR: Brian Kelly, 8/16/99
/
/ ARGUMENTS:
/ struct server_t s - the server strcture
/ struct game_t this_game - pointer to the player we're checking
/
/ RETURN VALUE: none
/
/ DESCRIPTION:
/ Process arguments, initialize program, and loop forever processing
/ player input.
/
****************************************************************************/
Do_setup_it_combat(struct client_t *c, struct game_t *theGame)
{
float ftemp;
/* WARNING: c->realm->realm_lock is passed LOCKED! */
/*
Do_lock_mutex(&c->realm->realm_lock);
*/
struct it_combat_t *theCombat;
struct event_t *event_ptr;
struct it_combat_t *it_combat_ptr;
char string_buffer[SZ_LINE];
theCombat = (struct it_combat_t *) Do_malloc(SZ_IT_COMBAT);
theCombat->opponentFlag[0] = FALSE;
theCombat->opponentFlag[1] = FALSE;
theCombat->next_opponent = NULL;
theCombat->player_ptr = NULL;
Do_init_mutex(&theCombat->theLock);
c->game->it_combat = theCombat;
if (theGame->it_combat == NULL) {
theGame->it_combat = theCombat;
Do_unlock_mutex(&c->realm->realm_lock);
event_ptr = (struct event_t *) Do_create_event();
event_ptr->type = IT_COMBAT_EVENT;
event_ptr->arg4 = theCombat;
event_ptr->to = theGame;
event_ptr->from = c->game;
Do_send_event(event_ptr);
Do_send_clear(c);
if (c->player.blind)
sprintf(string_buffer,
"You hear another player nearby!\n");
else
sprintf(string_buffer,
"You see another player in the distance!\n");
}
else {
it_combat_ptr = theGame->it_combat;
while (it_combat_ptr->next_opponent != NULL)
it_combat_ptr = it_combat_ptr->next_opponent;
it_combat_ptr->next_opponent = theCombat;
Do_unlock_mutex(&c->realm->realm_lock);
Do_send_clear(c);
if (c->player.blind)
sprintf(string_buffer,
"You sense that several players are nearby!\n");
else
sprintf(string_buffer,
"You see several players in the distance!\n");
}
Do_send_line(c, string_buffer);
Do_lock_mutex(&theCombat->theLock);
Do_opponent_struct(c, &theCombat->opponent[0]);
c->battle.opponent = &theCombat->opponent[1];
Do_unlock_mutex(&theCombat->theLock);
/* for attacking another player, pick up sin */
Do_sin(c, .5);
sprintf(string_buffer, "%s ATTACKED another player.\n", c->player.lcname);
Do_log(BATTLE_LOG, string_buffer);
Do_send_line(c, "Waiting for the other player(s)...\n");
Do_it_combat_turns(c, theCombat, &theCombat->opponent[0],
&theCombat->opponentFlag[0], &theCombat->opponentFlag[1]);
return;
}
/***************************************************************************
/ FUNCTION NAME: Do_it_combat(struct client_t *c, struct event_t *theEvent)
/
/ FUNCTION: Check to see if a player entered an occupied square
/
/ AUTHOR: Brian Kelly, 8/16/99
/
/ ARGUMENTS:
/ struct server_t s - the server strcture
/ struct game_t this_game - pointer to the player we're checking
/
/ RETURN VALUE: none
/
/ DESCRIPTION:
/ Process arguments, initialize program, and loop forever processing
/ player input.
/
****************************************************************************/
Do_it_combat(struct client_t *c, struct event_t *theEvent, int available)
{
struct it_combat_t *theCombat;
char string_buffer[SZ_LINE];
Do_send_clear(c);
theCombat = (struct it_combat_t *) theEvent->arg4;
Do_lock_mutex(&theCombat->theLock);
/* if our flag is set, there is a problem */
if (!theCombat->opponentFlag[1]) {
theCombat->opponentFlag[0] = TRUE;
theCombat->opponentFlag[1] = FALSE;
Do_opponent_struct(c, &theCombat->opponent[1]);
if (c->player.energy <= 0) {
theCombat->message = IT_JUST_DIED;
Do_unlock_mutex(&theCombat->theLock);
kill(theCombat->opponent[0].processID ,SIGIO);
Do_lock_mutex(&c->realm->realm_lock);
c->game->it_combat = NULL;
Do_unlock_mutex(&c->realm->realm_lock);
return;
}
else if (!available) {
theCombat->message = IT_JUST_LEFT;
Do_unlock_mutex(&theCombat->theLock);
kill(theCombat->opponent[0].processID ,SIGIO);
Do_lock_mutex(&c->realm->realm_lock);
c->game->it_combat = NULL;
Do_unlock_mutex(&c->realm->realm_lock);
return;
}
else {
theCombat->message = IT_REPORT;
}
}
c->battle.opponent = &theCombat->opponent[0];
if (c->player.blind) {
if (c->stuck) {
c->stuck = FALSE;
sprintf(string_buffer,
"Before you can move, you hear another player in the area!\n");
}
else {
sprintf(string_buffer,
"You hear another player approach!\n");
}
}
else {
if (c->stuck) {
c->stuck = FALSE;
sprintf(string_buffer,
"Before you can move, %s enters the area!\n",
theCombat->opponent[0].name);
}
else {
sprintf(string_buffer,
"You see %s approaching from the distance!\n",
theCombat->opponent[0].name);
}
}
Do_unlock_mutex(&theCombat->theLock);
kill(theCombat->opponent[0].processID ,SIGIO);
Do_send_line(c, string_buffer);
Do_send_buffer(c);
sleep(2);
Do_it_combat_turns(c, theCombat, &theCombat->opponent[1],
&theCombat->opponentFlag[1], &theCombat->opponentFlag[0]);
return;
}
/***************************************************************************
/ FUNCTION NAME: void Do_it_combat_turn(struct client_t *c, struct it_combat_t *theCombat, struct opponent_t *myStats, bool *my Flag, bool *hisFlag)
/
/ FUNCTION: Check to see if a player entered an occupied square
/
/ AUTHOR: Brian Kelly, 8/16/99
/
/ ARGUMENTS:
/ struct server_t s - the server strcture
/ struct game_t this_game - pointer to the player we're checking
/
/ RETURN VALUE: none
/
/ MODULES CALLED: monstlist(), checkenemy(), activelist(),
/ throneroom(), checkbattle(), readmessage(), changestats(), writerecord()
,
/ tradingpost(), adjuststats(), recallplayer(), displaystats(), checktampe
red(),
/ fabs(), rollnewplayer(), time(), exit(), sqrt(), floor(), wmove(),
/ signal(), strcat(), purgeoldplayers(), getuid(), isatty(), wclear(),
/ strcpy(), system(), altercoordinates(), cleanup(), waddstr(), procmain()
,
/ playinit(), leavegame(), localtime(), getanswer(), neatstuff(), initials
tate(),
/ scorelist(), titlelist()
/
/ DESCRIPTION:
/ Process arguments, initialize program, and loop forever processing
/ player input.
/
****************************************************************************/
Do_it_combat_turns(struct client_t *c, struct it_combat_t *theCombat,
struct opponent_t *myStats, bool *myFlag, bool *hisFlag)
{
short theMessage;
double theArg;
short newMessage;
double newArg;
char string_buffer[SZ_LINE];
char error_msg[SZ_ERROR_MESSAGE];
struct event_t *event_ptr;
struct realm_object_t *object_ptr;
float ftemp;
for (;;) {
c->timeoutFlag = 0;
Do_wait_flag(c, myFlag, &theCombat->theLock);
/* handle our flag */
Do_lock_mutex(&theCombat->theLock);
/* see if the player timed out */
if (c->timeoutFlag && theCombat->message != IT_BORED) {
theMessage = IT_ABANDON;
}
else {
theMessage = theCombat->message;
theArg = theCombat->arg1;
*myFlag = FALSE;
}
/* unlock the flags so the other thread can check it */
Do_unlock_mutex(&theCombat->theLock);
/* if the other thread received an event, we're server */
if (theMessage == IT_REPORT) {
if (c->player.blind)
sprintf(string_buffer,
"You have encountered another player.\n");
else {
sprintf(string_buffer, "You have encountered %s.\n",
c->battle.opponent->name);
Do_send_line(c, string_buffer);
}
/* defender always attacks first */
theMessage = IT_DEFEND;
}
/* battle continues, decide who goes next */
if (theMessage == IT_CONTINUE) {
if (RND() * c->battle.opponent->speed > RND() *
myStats->speed) {
theMessage = IT_DEFEND;
}
else
theMessage = IT_ECHO;
}
/* if the opponent just left the game */
if (theMessage == IT_JUST_LEFT) {
sprintf(string_buffer,
"You arrive just to see %s vanish from the realm.\n",
c->battle.opponent->name);
Do_send_line(c, string_buffer);
c->battle.opponent->experience = 0.0;
theMessage = IT_DEFEAT;
}
/* if the opponent passes on combat */
if (theMessage == IT_JUST_DIED) {
sprintf(string_buffer, "%s falls dead at your feet.\n",
c->battle.opponent->name);
Do_send_line(c, string_buffer);
c->battle.opponent->experience = 0.0;
theMessage = IT_DEFEAT;
}
/* if the opponent passes on combat */
if (theMessage == IT_BORED) {
sprintf(string_buffer,
"%s became bored and left the battlefield.\n",
c->battle.opponent->name);
Do_send_line(c, string_buffer);
c->battle.opponent->experience = 0.0;
theMessage = IT_DEFEAT;
}
/* if the opponent is having network trouble */
if (theMessage == IT_CONCEDE) {
sprintf(string_buffer, "%s concedes the battle.\n",
c->battle.opponent->name);
Do_send_line(c, string_buffer);
theMessage = IT_DEFEAT;
}
newMessage = IT_CONTINUE;
string_buffer[0] = '\0';
switch (theMessage) {
/* we've encountered a problem - every thread for himself */
case IT_ABANDON:
sprintf(error_msg,
"[%s] now abandoning it_combat in Do_it_combat_turns.\n",
c->connection_id);
Do_log_error(error_msg);
/* leave a message for our opponent */
theCombat->message = IT_BORED;
Do_lock_mutex(&theCombat->theLock);
*hisFlag = TRUE;
Do_unlock_mutex(&theCombat->theLock);
kill(c->battle.opponent->processID, SIGIO);
/* clear any spells */
Do_energy(c, c->player.energy, c->player.max_energy,
c->player.shield, 0.0, FALSE);
Do_strength(c, c->player.max_strength, c->player.sword, 0, FALSE);
Do_speed(c, c->player.max_quickness, c->player.quicksilver, 0,
FALSE);
/* pull ourselves out of combat */
Do_lock_mutex(&c->realm->realm_lock);
c->game->it_combat = NULL;
c->game->virtual = TRUE;
Do_unlock_mutex(&c->realm->realm_lock);
/* get away from this square and this battle */
event_ptr = (struct event_t *) Do_create_event();
event_ptr->to = c->game;
event_ptr->from = c->game;
event_ptr->type = MOVE_EVENT;
event_ptr->arg3 = A_NEAR;
Do_file_event(c, event_ptr);
return;
/* we decided to attack, so have the opponent echo an attack */
case IT_ECHO:
newMessage = IT_DEFEND;
break;
/* we are to attack */
case IT_ATTACK:
/* give the character fatigue */
++c->battle.rounds;
Do_speed(c, c->player.max_quickness, c->player.quicksilver,
c->battle.speedSpell, FALSE);
myStats->speed = c->player.quickness;
/* if the player has a ring in use */
if (c->battle.ring_in_use) {
/* age ring */
if (c->player.ring_type != R_DLREG) {
--c->player.ring_duration;
}
/* regardless of ring type, heal the character */
Do_energy(c, c->player.max_energy + c->player.shield,
c->player.max_energy, c->player.shield,
c->battle.force_field, FALSE);
}
Do_send_line(c,
"You attack this round. Please choose your attack:\n");
Do_playerhits(c, &newMessage, &newArg);
/* if the player put up a shield, copy the info over */
if (newMessage == IT_SHIELD) {
myStats->shield = c->battle.force_field;
}
break;
/* we are to defend */
case IT_DEFEND:
sprintf(string_buffer,
"%s attacks for this round. Please wait for a decision.\n",
c->battle.opponent->name);
newMessage = IT_ATTACK;
break;
/* the other thread is declaring victory */
case IT_VICTORY:
newMessage = IT_DEFEAT;
/* clear any spells */
Do_energy(c, c->player.energy, c->player.max_energy,
c->player.shield, 0.0, FALSE);
Do_strength(c, c->player.max_strength, c->player.sword, 0, FALSE);
Do_speed(c, c->player.max_quickness, c->player.quicksilver, 0,
FALSE);
c->battle.force_field = 0;
c->battle.strengthSpell = 0;
c->battle.speedSpell = 0;
break;
/* the other thread stands defeated - we clean up */
case IT_DEFEAT:
/* award experience if there is any to be had */
if (c->battle.opponent->experience) {
Do_experience(c, c->battle.opponent->experience, FALSE);
/* for killing another player, pick up sin */
Do_sin(c, sqrt(c->battle.opponent->size) / 3.1);
sprintf(error_msg, "%s KILLED %s in IT combat.\n", c->player.lcname,
c->battle.opponent->name);
Do_log(BATTLE_LOG, error_msg);
}
/* clear any spells */
Do_energy(c, c->player.energy, c->player.max_energy,
c->player.shield, 0.0, FALSE);
Do_strength(c, c->player.max_strength, c->player.sword, 0, FALSE);
Do_speed(c, c->player.max_quickness, c->player.quicksilver, 0,
FALSE);
c->battle.force_field = 0;
c->battle.strengthSpell = 0;
c->battle.speedSpell = 0;
/* if we're in the throne room and are not king */
/* become king NOW (another battle may be pending) */
if (c->player.location == PL_THRONE && c->player.special_type !=
SC_KING && c->player.special_type != SC_STEWARD) {
/* become steward */
if (c->player.level >= 10 && c->player.level < 200) {
Do_steward(c);
}
else if (c->player.level >= 1000 && c->player.level < 2000) {
Do_king(c);
}
}
Do_lock_mutex(&c->realm->realm_lock);
/* if there are no more battles to fight */
if (theCombat->next_opponent == NULL) {
/* pull ourselves out of combat */
c->game->it_combat = NULL;
Do_unlock_mutex(&c->realm->realm_lock);
/* create a body event for ourselves */
/* opponent put player struct here if he will die */
if (theCombat->player_ptr != NULL) {
event_ptr = (struct event_t *) Do_create_event();
event_ptr->to = c->game;
event_ptr->from = c->game;
event_ptr->type = CORPSE_EVENT;
/* the body can be cursed */
event_ptr->arg1 = TRUE;
event_ptr->arg4 = theCombat->player_ptr;
Do_file_event(c, event_ptr);
}
}
/* if there are more opponents to fight */
else {
event_ptr = (struct event_t *) Do_create_event();
event_ptr->to = c->game;
event_ptr->from = c->game;
event_ptr->type = IT_COMBAT_EVENT;
event_ptr->arg4 = (void *)theCombat->next_opponent;
Do_file_event(c, event_ptr);
/* put ourselves back in combat */
c->game->it_combat = theCombat->next_opponent;
/* create a realm object for this kill, if necessary */
if (theCombat->player_ptr != NULL) {
object_ptr = (struct realm_object_t *)
Do_malloc(SZ_REALM_OBJECT);
object_ptr->x = c->player.x;
object_ptr->y = c->player.y;
object_ptr->type = CORPSE;
object_ptr->arg1 = theCombat->player_ptr;
object_ptr->next_object = c->realm->objects;
c->realm->objects = object_ptr;
}
Do_unlock_mutex(&c->realm->realm_lock);
}
Do_unlock_mutex(&theCombat->theLock);
Do_destroy_mutex(&theCombat->theLock);
free((void *)theCombat);
Do_send_line(c, "You are victorious!\n");
Do_more(c);
Do_send_clear(c);
return;
case IT_MELEE:
sprintf(string_buffer,
"%s melees with you hitting %.0f times!\n",
c->battle.opponent->name, theArg);
Do_energy(c, myStats->energy, c->player.max_energy,
c->player.shield, myStats->shield, FALSE);
break;
case IT_SKIRMISH:
sprintf(string_buffer,
"%s skirmishes with you hitting %.0f times!\n",
c->battle.opponent->name, theArg);
Do_energy(c, myStats->energy, c->player.max_energy,
c->player.shield, myStats->shield, FALSE);
break;
case IT_NICKED:
c->battle.opponent->experience += theArg;
theArg *= 30.0 * c->player.level + 1.0;
sprintf(string_buffer,
"%s nicks you taking %.0f experience!\n",
c->battle.opponent->name, theArg);
Do_energy(c, myStats->energy, c->player.max_energy,
c->player.shield, myStats->shield, FALSE);
Do_speed(c, c->player.max_quickness, c->player.quicksilver,
c->battle.speedSpell + 2, FALSE);
/* only subtract positive values, characters managed to
get negative experience */
if (theArg > 0) {
c->player.experience -= theArg;
}
break;
case IT_EVADED:
sprintf(string_buffer, "%s flees the battle!\n",
c->battle.opponent->name);
c->battle.opponent->experience = 0;
newMessage = IT_VICTORY;
break;
case IT_WIZEVADE:
sprintf(string_buffer, "%s laughs at your pitiful attack and teleports away!\n",
c->battle.opponent->name);
c->battle.opponent->experience = 0;
newMessage = IT_VICTORY;
break;
case IT_NO_EVADE:
sprintf(string_buffer,
"%s tried to flee, but couldn't shake you!\n",
c->battle.opponent->name);
break;
case IT_LUCKOUT:
sprintf(string_buffer, "%s successfully lucks out in the battle!\n",
c->battle.opponent->name);
Do_energy(c, myStats->energy, c->player.max_energy,
c->player.shield, myStats->shield, FALSE);
break;
case IT_NO_LUCKOUT:
sprintf(string_buffer,
"%s failed to luckout in the battle!\n",
c->battle.opponent->name);
break;
case IT_RING:
sprintf(string_buffer, "%s puts on a ring!\n",
c->battle.opponent->name);
break;
case IT_NO_RING:
sprintf(string_buffer, "%s searches in vain for a ring!\n",
c->battle.opponent->name);
break;
case IT_ALL_OR_NOT:
sprintf(string_buffer,
"%s casts All or Nothing, blasting you for %.0f damage!\n",
c->battle.opponent->name, theArg);
Do_energy(c, myStats->energy, c->player.max_energy,
c->player.shield, myStats->shield, FALSE);
break;
case IT_NO_ALL_OR_NOT:
sprintf(string_buffer,
"%s flubs an attempt to cast All or Nothing!\n",
c->battle.opponent->name);
break;
case IT_BOLT:
sprintf(string_buffer,
"%s hit you with a %.0f damage Mana Bolt!\n",
c->battle.opponent->name, theArg);
Do_energy(c, myStats->energy, c->player.max_energy,
c->player.shield, myStats->shield, FALSE);
break;
case IT_NO_BOLT:
sprintf(string_buffer,
"%s casts a Mana Bolt that peters out!\n",
c->battle.opponent->name);
break;
case IT_SHIELD:
sprintf(string_buffer, "%s throws up a Force Shield!\n",
c->battle.opponent->name);
break;
case IT_NO_SHIELD:
sprintf(string_buffer, "%s messes up a Force Shield spell!\n",
c->battle.opponent->name);
break;
case IT_TRANSFORM:
Do_lock_mutex(&c->realm->monster_lock);
sprintf(string_buffer,
"%s casts Transform, turning you into %s!\n",
c->battle.opponent->name,
c->realm->monster[(int)theArg].name);
event_ptr = (struct event_t *) Do_create_event();
event_ptr->type = DEATH_EVENT;
event_ptr->arg1 = theArg;
event_ptr->arg3 = K_TRANSFORMED;
Do_unlock_mutex(&c->realm->monster_lock);
Do_handle_event(c, event_ptr);
newMessage = IT_DEFEAT;
break;
case IT_NO_TRANSFORM:
sprintf(string_buffer, "%s fails to cast a Transform spell!\n",
c->battle.opponent->name);
break;
case IT_TRANSFORM_BACK:
sprintf(string_buffer,
"%s's Transform spell backfires! %s turns into %s!\n",
c->battle.opponent->name, c->battle.opponent->name,
c->realm->monster[(int)theArg].name);
Do_cancel_monster(c->battle.opponent);
newMessage = IT_VICTORY;
break;
case IT_MIGHT:
sprintf(string_buffer,
"%s buffs up with an Increase Might spell!\n",
c->battle.opponent->name);
c->battle.opponent->strength += c->player.max_strength;
break;
case IT_NO_MIGHT:
sprintf(string_buffer,
"%s flounders with an Increase Might spell!\n",
c->battle.opponent->name);
break;
case IT_HASTE:
sprintf(string_buffer,
"%s casts a Haste spell and speeds up!\n",
c->battle.opponent->name);
c->battle.opponent->strength += c->player.max_quickness;
break;
case IT_NO_HASTE:
sprintf(string_buffer,
"%s casts an ineffective Haste spell!\n",
c->battle.opponent->name);
break;
case IT_TRANSPORT:
sprintf(string_buffer,
"%s sends you away with a Transport spell!\n",
c->battle.opponent->name);
event_ptr = (struct event_t *) Do_create_event();
event_ptr->type = MOVE_EVENT;
event_ptr->arg3 = A_FAR;
Do_file_event(c, event_ptr);
newMessage = IT_DEFEAT;
break;
case IT_NO_TRANSPORT:
sprintf(string_buffer,
"%s misfires a Transport spell!\n",
c->battle.opponent->name);
break;
case IT_TRANSPORT_BACK:
sprintf(string_buffer,
"%s is transported away from a bounced Transport spell!\n",
c->battle.opponent->name);
Do_cancel_monster(c->battle.opponent);
newMessage = IT_VICTORY;
break;
case IT_PARALYZE:
sprintf(string_buffer,
"%s casts a Paralyze spell holding you in place!\n",
c->battle.opponent->name);
break;
case IT_NO_PARALYZE:
sprintf(string_buffer, "%s casts a dud Paralyze spell!\n",
c->battle.opponent->name);
break;
case IT_PASS:
sprintf(string_buffer, "%s whistles a happy tune.\n",
c->battle.opponent->name);
break;
default:
sprintf(error_msg,
"[%s] Unknown combat message %d in Do_it_combat_turn.\n",
c->connection_id, theMessage);
Do_log_error(error_msg);
theCombat->message = IT_ABANDON;
Do_lock_mutex(&theCombat->theLock);
*hisFlag = TRUE;
Do_unlock_mutex(&theCombat->theLock);
kill(c->battle.opponent->processID, SIGIO);
Do_lock_mutex(&c->realm->realm_lock);
c->game->it_combat = NULL;
c->game->virtual = TRUE;
Do_unlock_mutex(&c->realm->realm_lock);
c->run_level = EXIT_THREAD;
return;
}
if (strlen(string_buffer))
Do_send_line(c, string_buffer);
/* if the character has died */
if (c->player.energy <= 0.0) {
newMessage = IT_DEFEAT;
event_ptr = (struct event_t *) Do_create_event();
event_ptr->type = DEATH_EVENT;
event_ptr->arg3 = K_IT_COMBAT;
event_ptr->arg4 = (void *)
Do_malloc(strlen(c->battle.opponent->name) + 1);
strcpy(event_ptr->arg4, c->battle.opponent->name);
/* if we leave a corpse */
if (c->player.level < 3000 && c->player.special_type != SC_KING &&
(!c->battle.ring_in_use || !(c->player.ring_type ==
R_DLREG || c->player.ring_type == R_NAZREG))) {
/* create a copy of ourselves for the corpse */
theCombat->player_ptr = (struct player_t *)
Do_copy_record(&c->player, FALSE);
}
Do_handle_event(c, event_ptr);
}
/* if we lost, remove us from battle completely */
/* otherwise the winner could encounter us again before we move */
if (newMessage == IT_DEFEAT || newMessage == IT_EVADED) {
Do_lock_mutex(&c->realm->realm_lock);
c->game->it_combat = NULL;
c->game->virtual = TRUE;
Do_unlock_mutex(&c->realm->realm_lock);
}
/* send off the new message */
theCombat->message = newMessage;
theCombat->arg1 = newArg;
Do_lock_mutex(&theCombat->theLock);
*hisFlag = TRUE;
Do_unlock_mutex(&theCombat->theLock);
kill(c->battle.opponent->processID, SIGIO);
if (c->player.poison > 0.0)
myStats->energy = c->player.energy;
if (newMessage == IT_DEFEAT) {
Do_orphan_events(c);
Do_more(c);
Do_send_clear(c);
return;
}
}
}