Beispiel #1
0
void do_copyover(void) {
  LIST_ITERATOR *sock_i = newListIterator(socket_list);
  SOCKET_DATA     *sock = NULL;
  FILE *fp;
  char buf[100];
  char control_buf[20];
  char port_buf[20];

  if ((fp = fopen(COPYOVER_FILE, "w+")) == NULL)
    return;

  sprintf(buf, "\n\r <*>            The world starts spinning             <*>\n\r");

  // For each playing descriptor, save its character and account
  ITERATE_LIST(sock, sock_i) {
    compressEnd(sock, sock->compressing, FALSE);
    // kick off anyone who hasn't yet logged in a character
    if (!socketGetChar(sock) || !socketGetAccount(sock) || 
	!charGetRoom(socketGetChar(sock))) {
      text_to_socket(sock, "\r\nSorry, we are rebooting. Come back in a few minutes.\r\n");
      close_socket(sock, FALSE);
    }
    // save account and player info to file
    else {
      fprintf(fp, "%d %s %s %s\n",
	      sock->control, accountGetName(sock->account), 
	      charGetName(sock->player), sock->hostname);
      // save the player
      save_player(sock->player);
      save_account(sock->account);
      text_to_socket(sock, buf);
    }
  } deleteListIterator(sock_i);
bool event_mobile_save(EVENT_DATA *event)
{
  D_MOBILE *dMob;

  /* Check to see if there is an owner of this event.
   * If there is no owner, we return TRUE, because
   * it's the safest - and post a bug message.
   */
  if ((dMob = event->owner.dMob) == NULL)
  {
    bug("event_mobile_save: no owner.");
    return TRUE;
  }

  /* save the actual player file */
  save_player(dMob);

  /* enqueue a new event to save the pfile in 2 minutes */
  event = alloc_event();
  event->fun = &event_mobile_save;
  event->type = EVENT_MOBILE_SAVE;
  add_event_mobile(event, dMob, 2 * 60 * PULSES_PER_SECOND);

  return FALSE;
}
Beispiel #3
0
bool save_game(char *filename)
{
        char cmd[260];
        int i;
        FILE *f;
        struct savefile_header header;
        //int i;
        monster_t *m;
        obj_t *o;

        gtprintf("Saving game to file %s", filename);
        f = fopen(filename, "w");

        header.magic = GT_SAVEFILE_MAGIC;
        header.version.major = GT_VERSION_MAJ;
        header.version.minor = GT_VERSION_MIN;
        header.version.revision = GT_VERSION_REV;

        fwrite(&header, sizeof(struct savefile_header), 1, f);
        fwrite(&gtconfig, sizeof(gt_config_t), 1, f);
        fwrite(game, sizeof(game_t), 1, f);

        /* then, let's save the player */
        save_player(player, f);

        m = monsterdefs->head;
        for(i=0; i <= game->monsterdefs; i++) {
                if(m)
                        save_monsterdef(m, f);
                m = m->next;
        }

        o = objdefs->head;
        for(i=0; i <= game->objdefs; i++) {
                if(o)
                        save_objdef(o, f);
                o = o->next;
        }

        /* then, let's save world and levels */
        save_level(world->dng, f);

        for(i=1; i<=game->createddungeons; i++)
                save_level(&world->dng[i], f);

        /* finally, the eventlist */
        save_eventlist(f);

        fclose(f);

        if(gtconfig.compress_savefile) {
                sprintf(cmd, "xz %s", filename);
                system(cmd);
        }

        gtprintf("Saving successful!");
        return true;
}
Beispiel #4
0
void CubeCreature::save_cube(FILE *file){
	fprintf(file,"%u ",energy);
	save_address(file);
	carry_res.save(file);
	orders->save_orders(file);
	save_player(file);
	save_colli(file);
	save_creature(file);
	save_constructable(file);
	save_health(file);
}
Beispiel #5
0
/**
 * Remove a player from the game that has been disconnected by logging
 * out, the socket connection was interrupted, etc.
 * @param pl The player to remove. */
void remove_ns_dead_player(player *pl)
{
	if (pl == NULL || pl->ob->type == DEAD_OBJECT)
	{
		return;
	}

	if (pl->state == ST_PLAYING)
	{
		/* Trigger the global LOGOUT event */
		trigger_global_event(GEVENT_LOGOUT, pl->ob, pl->socket.host);

		if (!pl->dm_stealth)
		{
			new_draw_info_format(NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, NULL, "%s left the game.", query_name(pl->ob, NULL));
		}

		/* If this player is in a party, leave the party */
		if (pl->party)
		{
			command_party(pl->ob, "leave");
		}

		strncpy(pl->killer, "left", MAX_BUF - 1);
		hiscore_check(pl->ob, 1);

		/* Be sure we have closed container when we leave */
		container_unlink(pl, NULL);

		save_player(pl->ob, 0);

		if (!QUERY_FLAG(pl->ob, FLAG_REMOVED))
		{
			leave_map(pl->ob);
		}

		if (pl->ob->map)
		{
			if (pl->ob->map->in_memory == MAP_IN_MEMORY)
			{
				pl->ob->map->timeout = MAP_TIMEOUT(pl->ob->map);
			}

			pl->ob->map = NULL;
		}
	}

	LOG(llevInfo, "LOGOUT: >%s< from IP %s\n", pl->ob->name, pl->socket.host);

	/* To avoid problems with inventory window */
	pl->ob->type = DEAD_OBJECT;
	free_player(pl);
}
Beispiel #6
0
bool Tile_map::save()
{
    std::ofstream file(map_info.filename , std::ios_base::out | std::ios_base::binary );
    uint8_t * buffer = new uint8_t (8);
    buffer[0] = 0xA9;
    buffer[1] = 0xB2;
    buffer[2] = 0x18;
    buffer[3] = 0x04;
    buffer[4] = 0xE1;
    buffer[5] = 0x64;
    buffer[6] = 0xF5;
    buffer[7] = 0x9D;
    // initialize the map by checksum
    for(int a=0 ; a < 8 ; a++)
    {
        file<<buffer[a];
    }
    delete [] buffer;
    // save major and minor map version
    file<<map_info.major_version;
    file<<map_info.minor_version;
    // save map name
    file<<map_info.map_name<<'\n';
    file<<map_info.width<<' ';
    file<<map_info.height<<' ';
    if(player)
    {
        file<<Chunk_type::player<<' ';
        save_player(file);
    }
    for(auto & a : sets_of_tiles)
    {
        file<<Chunk_type::tile_set<<' ';
        save_tile_set(file,a);
    }
    for(auto & a : types_of_tile)
    {
        file<<Chunk_type::tile_type<<' ';
        save_tile_type(file,a);
    }
    for(auto & a : tiles)
    {
        file<<Chunk_type::tile<<' ';
        save_tile(file,a);
    }
    if(background)
    {
        file<<Chunk_type::background<<' ';
        save_background(file);
    }

    return true;
}
Beispiel #7
0
/*
 * Handle signal -- abort, kill, etc
 */
static void handle_signal_abort(int sig)
{
	/* Disable handler */
	(void)(*signal_aux)(sig, SIG_IGN);


	/* Nothing to save, just quit */
	if (!character_generated || character_saved) quit(NULL);


	/* Clear the bottom line */
	Term_erase(0, 23, 255);

	/* Give a warning */
	Term_putstr(0, 23, -1, TERM_RED,
	            "A gruesome software bug LEAPS out at you!");

	/* Message */
	Term_putstr(45, 23, -1, TERM_RED, "Panic save...");

	/* Flush output */
	Term_fresh();

	/* Panic Save */
	p_ptr->panic_save = 1;

	/* Panic save */
	strcpy(p_ptr->died_from, "(panic save)");

	/* Forbid suspend */
	signals_ignore_tstp();

	/* Attempt to save */
	if (save_player())
	{
		Term_putstr(45, 23, -1, TERM_RED, "Panic save succeeded!");
	}

	/* Save failed */
	else
	{
		Term_putstr(45, 23, -1, TERM_RED, "Panic save failed!");
	}

	/* Flush output */
	Term_fresh();

	/* Quit */
	quit("software bug");
}
void player_death(void)
{
    /* Try to make a player ghost template */
    add_player_ghost_entry();

    /* Retire in the town in a good state */
    if (p_ptr->total_winner)
    {
        p_ptr->depth = 0;
        p_ptr->died_from = "Ripe Old Age";
        p_ptr->exp = p_ptr->max_exp;
        p_ptr->lev = p_ptr->max_lev;
        p_ptr->au += 10000000L;

        display_winner();
    }

    QDate today = QDate::currentDate();
    QTime right_now = QTime::currentTime();
    QString long_day = QString("%1 at %2") .arg(today.toString()) .arg(right_now.toString());

    write_death_note(long_day);

    print_tomb();
    death_knowledge();
    enter_score(long_day);

    /* Save dead player */
    if (!save_player())
    {
        message(QString("death save failed!"));
    }

    // Hack - update everything onscreen
    ui_redraw_all();

    // Automatic character dump
    if (death_char_dump)
    {
        save_character_file();
        save_screenshot(FALSE);
    }

    p_ptr->in_death_menu = TRUE;
    PlayerDeathDialog();
    p_ptr->in_death_menu = FALSE;
}
Beispiel #9
0
/* sync player files corresponding to one letter */
void		sync_to_file(char c, int background)
{
  saved_player *scan, **hash;
  char		*oldstack;
  int		i;
  player	*online;
  
  if(background && fork())
    return;
    
  oldstack = stack;
  if(sys_flags & VERBOSE) {
    sprintf(oldstack, "Syncing File '%c'.", c);
    stack = end_string(oldstack);
    log("sync", oldstack);
    stack = oldstack;
  }
  
  sys_flags |= INVIS_SAVE;
  
  hash = saved_hash[((int) c - (int) 'a')];
  for(i=0; i<HASH_SIZE; i++, hash++)
    for(scan=*hash; scan; scan=scan->next) {
      /* are they online? */
      online = find_player_absolute_quiet(scan->lower_name);
      if(online)
        save_player(online);
        
      if(scan->cache>=0)
        sync_cache_item_to_disk(scan->cache);
      write_to_file(scan);
    }
    
  sys_flags &= ~INVIS_SAVE;
  update[(int) c - (int) 'a'] = 0;
  stack = oldstack;
  
  if(background)
    exit(0);
}
Beispiel #10
0
/*
 * Handle abrupt death of the visual system
 *
 * This routine is called only in very rare situations, and only
 * by certain visual systems, when they experience fatal errors.
 *
 * XXX XXX Hack -- clear the death flag when creating a HANGUP
 * save file so that player can see tombstone when restart.
 *
 * TODO: Hookify
 */
void exit_game_panic(void)
{
#ifndef AVT_HOOKIFY_EXIT
	/* If nothing important has happened, just quit */
	if (!character_generated || character_saved) quit("panic");
#endif

	/* Mega-Hack -- see "msg_print()" */
	msg_flag = FALSE;

	/* Clear the top line */
	prt("", 0, 0);

#ifndef AVT_HOOKIFY_EXIT
	/* Hack -- turn off some things */
	disturb(1, 0);

	/* Hack -- Delay death XXX XXX XXX */
	if (p_ptr->chp < 0) p_ptr->is_dead = FALSE;

	/* Hardcode panic save */
	p_ptr->panic_save = 1;
#endif

	/* Forbid suspend */
	signals_ignore_tstp();

#ifndef AVT_HOOKIFY_EXIT
	/* Indicate panic save */
	strcpy(p_ptr->died_from, "(panic save)");

	/* Panic save, or get worried */
	if (!save_player()) quit("panic save failed!");
#endif

	/* Successful panic save */
	quit("panic save succeeded!");
}
Beispiel #11
0
void process_players()
{
  player *scan,*su;
  char *oldstack;
  for(scan=flatlist_start;scan;scan=scan->flat_next) 
    if ((scan->fd<0) || (scan->flags&PANIC) || 
	(scan->flags&CHUCKOUT)) {
      
      oldstack=stack;
      current_player=scan;
      
      if (scan->location && scan->name[0] && !(scan->flags&RECONNECTION)) {
	sprintf(stack,"%s jumps up into the air and disappears with a loud *POP* !\n",full_name(scan));
	stack=end_string(stack);
	tell_room(scan->location,oldstack);
	stack=oldstack;
	save_player(scan);
      }
      if (!(scan->flags&RECONNECTION)) {
	  command_type=0;
	  do_inform(scan,"[%s has disconnected] %s");
	if (scan->saved && !(scan->flags&NO_SAVE_LAST_ON)) 
	    scan->saved->last_on=time(0);
      }
      
      if (sys_flags&VERBOSE) {
	if (scan->name[0])
	  sprintf(oldstack,"%s has disconnected.",scan->name);
	else
	  strcpy(oldstack,"Disconnect from login.");
	stack=end_string(oldstack);
	log("connection",oldstack);
    }
      destroy_player(scan);
      sys_flags|=ENFORCE_NO_NEW;
      for (su=flatlist_start;su;su=su->flat_next)
	  if (su->residency&OFF_DUTY) {
	      sys_flags&=~ENFORCE_NO_NEW;
	      break;
	  }
      current_player=0;
      stack=oldstack;
  }
    else 
	if (scan->flags&INPUT_READY) {
	    if (!(scan->lagged) && !(scan->flags&PERM_LAG)) {
		current_player=scan;
		current_room=scan->location;
		input_for_one(scan);
		action="processing players";
		current_player=0;
		current_room=0;
		
#ifdef PC
		if (scan->flags&PROMPT && scan==input_player) 
#else
		    if (scan->flags&PROMPT) 
#endif
			{
			    if (scan->saved_flags&CONVERSE) 
				do_prompt(scan,scan->converse_prompt);
			    else
				do_prompt(scan,scan->prompt);
			}
	    }
	memset(scan->ibuffer,0,IBUFFER_LENGTH);
	scan->flags &= ~INPUT_READY;
      }
}
Beispiel #12
0
/**
 * If the player should die (lack of hp, food, etc), we call this.
 *
 * Will remove diseases, apply death penalties, and so on.
 * @param op The player in jeopardy. */
void kill_player(object *op)
{
	char buf[HUGE_BUF];
	int x, y, i;
	/* this is for resurrection */
	mapstruct *map;
	object *tmp;
	int z;
	int num_stats_lose;
	int lost_a_stat;
	int lose_this_stat;
	int this_stat;

	if (pvp_area(NULL, op))
	{
		new_draw_info(NDI_UNIQUE | NDI_NAVY, op, "You have been defeated in combat!");
		new_draw_info(NDI_UNIQUE | NDI_NAVY, op, "Local medics have saved your life...");

		/* Restore player */
		cast_heal(op, MAXLEVEL, op, SP_CURE_POISON);
		/* Remove any disease */
		cure_disease(op, NULL);
		op->stats.hp = op->stats.maxhp;

		if (op->stats.food <= 0)
		{
			op->stats.food = 999;
		}

		/* Create a bodypart-trophy to make the winner happy */
		tmp = arch_to_object(find_archetype("finger"));

		if (tmp != NULL)
		{
			char race[MAX_BUF];

			snprintf(buf, sizeof(buf), "%s's finger", op->name);
			FREE_AND_COPY_HASH(tmp->name, buf);
			snprintf(buf, sizeof(buf), "This finger has been cut off %s the %s, when %s was defeated at level %d by %s.", op->name, player_get_race_class(op, race, sizeof(race)), gender_subjective[object_get_gender(op)], op->level, CONTR(op)->killer[0] == '\0' ? "something nasty" : CONTR(op)->killer);
			FREE_AND_COPY_HASH(tmp->msg, buf);
			tmp->value = 0, tmp->material = 0, tmp->type = 0;
			tmp->x = op->x, tmp->y = op->y;
			insert_ob_in_map(tmp, op->map, op, 0);
		}

		/* Teleport defeated player to new destination */
		transfer_ob(op, MAP_ENTER_X(op->map), MAP_ENTER_Y(op->map), 0, NULL, NULL);
		return;
	}

	if (save_life(op))
	{
		return;
	}

	/* Trigger the DEATH event */
	if (trigger_event(EVENT_DEATH, NULL, op, NULL, NULL, 0, 0, 0, SCRIPT_FIX_ALL))
	{
		return;
	}

	/* Trigger the global GDEATH event */
	trigger_global_event(EVENT_GDEATH, NULL, op);

	play_sound_player_only(CONTR(op), SOUND_PLAYER_DIES, SOUND_NORMAL, 0, 0);

	/* Save the map location for corpse, gravestone */
	x = op->x;
	y = op->y;
	map = op->map;

	/* Basically two ways to go - remove a stat permanently, or just
	 * make it depletion.  This bunch of code deals with that aspect
	 * of death. */
	if (settings.balanced_stat_loss)
	{
		/* If stat loss is permanent, lose one stat only. */
		/* Lower level chars don't lose as many stats because they suffer more
		   if they do. */
		if (settings.stat_loss_on_death)
		{
			num_stats_lose = 1;
		}
		else
		{
			num_stats_lose = 1 + op->level / BALSL_NUMBER_LOSSES_RATIO;
		}
	}
	else
	{
		num_stats_lose = 1;
	}

	lost_a_stat = 0;

	/* Only decrease stats if you are level 3 or higher. */
	for (z = 0; z < num_stats_lose; z++)
	{
		if (settings.stat_loss_on_death && op->level > 3)
		{
			/* Pick a random stat and take a point off it. Tell the
			 * player what he lost. */
			i = rndm(1, NUM_STATS) - 1;
			change_attr_value(&(op->stats), i, -1);
			check_stat_bounds(&(op->stats));
			change_attr_value(&(CONTR(op)->orig_stats), i, -1);
			check_stat_bounds(&(CONTR(op)->orig_stats));
			new_draw_info(NDI_UNIQUE, op, lose_msg[i]);
			lost_a_stat = 1;
		}
		else if (op->level > 3)
		{
			/* Deplete a stat */
			archetype *deparch = find_archetype("depletion");
			object *dep;

			i = rndm(1, NUM_STATS) - 1;
			dep = present_arch_in_ob(deparch, op);

			if (!dep)
			{
				dep = arch_to_object(deparch);
				insert_ob_in_ob(dep, op);
			}

			lose_this_stat = 1;

			if (settings.balanced_stat_loss)
			{
				/* Get the stat that we're about to deplete. */
				this_stat = get_attr_value(&(dep->stats), i);

				if (this_stat < 0)
				{
					int loss_chance = 1 + op->level / BALSL_LOSS_CHANCE_RATIO;
					int keep_chance = this_stat * this_stat;

					/* Yes, I am paranoid. Sue me. */
					if (keep_chance < 1)
					{
						keep_chance = 1;
					}

					/* There is a maximum depletion total per level. */
					if (this_stat < -1 - op->level / BALSL_MAX_LOSS_RATIO)
					{
						lose_this_stat = 0;
					}
					else
					{
						/* Take loss chance vs keep chance to see if we retain the stat. */
						if (rndm(0, loss_chance + keep_chance - 1) < keep_chance)
						{
							lose_this_stat = 0;
						}
					}
				}
			}

			if (lose_this_stat)
			{
				this_stat = get_attr_value(&(dep->stats), i);

				/* We could try to do something clever like find another
				 * stat to reduce if this fails.  But chances are, if
				 * stats have been depleted to -50, all are pretty low
				 * and should be roughly the same, so it shouldn't make a
				 * difference. */
				if (this_stat >= -50)
				{
					change_attr_value(&(dep->stats), i, -1);
					SET_FLAG(dep, FLAG_APPLIED);
					new_draw_info(NDI_UNIQUE, op, lose_msg[i]);
					fix_player(op);
					lost_a_stat = 1;
				}
			}
		}
	}

	/* If no stat lost, tell the player. */
	if (!lost_a_stat)
	{
		const char *god = determine_god(op);

		if (god && god != shstr_cons.none)
		{
			new_draw_info_format(NDI_UNIQUE, op, "For a brief moment you feel the holy presence of %s protecting you.", god);
		}
		else
		{
			new_draw_info(NDI_UNIQUE, op, "For a brief moment you feel a holy presence protecting you.");
		}
	}

	/* Put a gravestone up where the character 'almost' died. */
	tmp = arch_to_object(find_archetype("gravestone"));
	snprintf(buf, sizeof(buf), "%s's gravestone", op->name);
	FREE_AND_COPY_HASH(tmp->name, buf);
	FREE_AND_COPY_HASH(tmp->msg, gravestone_text(op));
	tmp->x = op->x, tmp->y = op->y;
	insert_ob_in_map(tmp, op->map, NULL, 0);

	/* Subtract the experience points, if we died because of food give us
	 * food, and reset HP... */

	/* Remove any poisoning the character may be suffering. */
	cast_heal(op, MAXLEVEL, op, SP_CURE_POISON);
	/* Remove any disease */
	cure_disease(op, NULL);

	/* Apply death experience penalty. */
	apply_death_exp_penalty(op);

	if (op->stats.food < 0)
	{
		op->stats.food = 900;
	}

	op->stats.hp = op->stats.maxhp;
	op->stats.sp = op->stats.maxsp;
	op->stats.grace = op->stats.maxgrace;

	hiscore_check(op, 1);

	/* Otherwise the highscore can get entries like 'xxx was killed by pudding
	 * on map Wilderness' even if they were killed in a dungeon. */
	CONTR(op)->killer[0] = '\0';

	/* Check to see if the player is in a shop. Ii so, then check to see
	 * if the player has any unpaid items. If so, remove them and put
	 * them back in the map. */
	tmp = get_map_ob(op->map, op->x, op->y);

	if (tmp && tmp->type == SHOP_FLOOR)
	{
		remove_unpaid_objects(op->inv, op);
	}

	/* Move player to his current respawn position (last savebed). */
	enter_player_savebed(op);

	/* Show a nasty message */
	new_draw_info(NDI_UNIQUE, op, "YOU HAVE DIED.");
	save_player(op, 1);
	return;
}
Beispiel #13
0
/**
 * Drop an object onto the floor.
 * @param op Player object.
 * @param tmp The object to drop.
 * @param nrof Number of items to drop (0 for all). */
void drop_object(object *op, object *tmp, long nrof)
{
	object *floor;

	if (QUERY_FLAG(tmp, FLAG_NO_DROP) && !QUERY_FLAG(op, FLAG_WIZ))
	{
		return;
	}

	if (op->type == PLAYER)
	{
		CONTR(op)->praying = 0;
	}

	if (QUERY_FLAG(tmp, FLAG_APPLIED))
	{
		/* Can't unapply it */
		if (apply_special(op, tmp, AP_UNAPPLY | AP_NO_MERGE))
		{
			return;
		}
	}

	if (tmp->type == CONTAINER)
	{
		container_unlink(NULL, tmp);
	}

	/* Trigger the DROP event */
	if (trigger_event(EVENT_DROP, op, tmp, NULL, NULL, nrof, 0, 0, SCRIPT_FIX_ACTIVATOR))
	{
		return;
	}

	/* We are only dropping some of the items. We split the current
	 * object off. */
	if (nrof && tmp->nrof != (uint32) nrof)
	{
		object *tmp2 = tmp, *tmp2_cont = tmp->env;
		tag_t tmp2_tag = tmp2->count;
		char err[MAX_BUF];
		tmp = get_split_ob(tmp, nrof, err, sizeof(err));

		if (!tmp)
		{
			new_draw_info(NDI_UNIQUE, op, err);
			return;
		}

		/* Tell the client what happened to the rest of the objects. tmp2
		 * is now the original object */
		if (op->type == PLAYER)
		{
			if (was_destroyed(tmp2, tmp2_tag))
			{
				esrv_del_item(CONTR(op), tmp2_tag, tmp2_cont);
			}
			else
			{
				esrv_send_item(op, tmp2);
			}
		}
	}
	else
	{
		remove_ob(tmp);

		if (check_walk_off(tmp, NULL, MOVE_APPLY_DEFAULT) != CHECK_WALK_OK)
		{
			return;
		}
	}

	if (QUERY_FLAG(tmp, FLAG_STARTEQUIP) || QUERY_FLAG(tmp, FLAG_UNPAID))
	{
		if (op->type == PLAYER)
		{
			new_draw_info_format(NDI_UNIQUE, op, "You drop the %s.", query_name(tmp, NULL));
			esrv_del_item(CONTR(op), tmp->count, tmp->env);

			if (QUERY_FLAG(tmp, FLAG_UNPAID))
			{
				new_draw_info(NDI_UNIQUE, op, "The shop magic put it back to the storage.");

				floor = GET_MAP_OB_LAYER(op->map, op->x, op->y, 0);

				/* If the player is standing on a unique shop floor or unique randomitems shop floor, drop the object back to the floor */
				if (floor && floor->type == SHOP_FLOOR && (QUERY_FLAG(floor, FLAG_IS_MAGICAL) || (floor->randomitems && QUERY_FLAG(floor, FLAG_CURSED))))
				{
					tmp->x = op->x;
					tmp->y = op->y;
					insert_ob_in_map(tmp, op->map, op, 0);
				}
			}
			else
			{
				new_draw_info(NDI_UNIQUE, op, "The god-given item vanishes to nowhere as you drop it!");
			}
		}

		fix_player(op);
		return;
	}

	/* If SAVE_INTERVAL is commented out, we never want to save
	 * the player here. */
#ifdef SAVE_INTERVAL
	if (op->type == PLAYER && !QUERY_FLAG(tmp, FLAG_UNPAID) && (tmp->nrof ? tmp->value * tmp->nrof : tmp->value > 2000) && (CONTR(op)->last_save_time + SAVE_INTERVAL) <= time(NULL))
	{
		save_player(op, 1);
		CONTR(op)->last_save_time = time(NULL);
	}
#endif

	floor = GET_MAP_OB_LAYER(op->map, op->x, op->y, 0);

	if (floor && floor->type == SHOP_FLOOR && !QUERY_FLAG(tmp, FLAG_UNPAID) && tmp->type != MONEY)
	{
		sell_item(tmp, op, -1);

		/* Ok, we have really sold it - not only dropped. Run this only
		 * if the floor is not magical (i.e., unique shop) */
		if (QUERY_FLAG(tmp, FLAG_UNPAID) && !QUERY_FLAG(floor, FLAG_IS_MAGICAL))
		{
			if (op->type == PLAYER)
			{
				new_draw_info(NDI_UNIQUE, op, "The shop magic put it to the storage.");
				esrv_del_item(CONTR(op), tmp->count, tmp->env);
			}

			fix_player(op);

			if (op->type == PLAYER)
			{
				esrv_send_item(op, op);
			}

			return;
		}
	}

	tmp->x = op->x;
	tmp->y = op->y;

	if (op->type == PLAYER)
	{
		esrv_del_item(CONTR(op), tmp->count, tmp->env);
	}

	insert_ob_in_map(tmp, op->map, op, 0);

	SET_FLAG(op, FLAG_NO_APPLY);
	remove_ob(op);
	insert_ob_in_map(op, op->map, op, INS_NO_MERGE | INS_NO_WALK_ON);
	CLEAR_FLAG(op, FLAG_NO_APPLY);

	/* Need to update the weight for the player */
	if (op->type == PLAYER)
	{
		fix_player(op);
		esrv_send_item(op, op);
	}
}
Beispiel #14
0
void            process_players()
{
   player         *scan;
   char           *oldstack;

   for (scan = flatlist_start; scan; scan = scan->flat_next)
   {
     if (scan->flat_next)
       if (((player *)scan->flat_next)->flat_previous != scan)
	 {
	   raw_wall("\n\n   -=> Non-terminated flatlist <=-\n\n");
	   raw_wall("\n\n   -=> Dumping end off of list <=-\n\n");
	   scan->flat_next=NULL;
	 }

      if ((scan->fd < 0) || (scan->flags & PANIC) ||
          (scan->flags & CHUCKOUT))
      {

         oldstack = stack;
         current_player = scan;

         if (scan->location && scan->name[0] && !(scan->flags & RECONNECTION))
         {
            sprintf(stack, " %s suddenly dissolve%s into a squintillion dots"
                           " that quickly disperse.\n",
                    scan->name, single_s(scan));
            stack = end_string(stack);
            tell_room(scan->location, oldstack);
            stack = oldstack;
            save_player(scan);
         }
         if (!(scan->flags & RECONNECTION))
         {
            command_type = 0;
	    if (scan->gender==PLURAL)
	      do_inform(scan, "[%s have disconnected] %s");
	    else
	      do_inform(scan, "[%s has disconnected] %s");
            if (scan->saved && !(scan->flags & NO_SAVE_LAST_ON))
               scan->saved->last_on = time(0);
         }
         if (sys_flags & VERBOSE || scan->residency == 0)
         {
            if (scan->name[0])
               sprintf(oldstack, "%s has disconnected from %s", scan->name,
                       scan->inet_addr);
            else
               sprintf(oldstack, "Disconnect from login. [%s]",
                       scan->inet_addr);
            stack = end_string(oldstack);
            log("newconn", oldstack);
         }
         destroy_player(scan);
         current_player = 0;
         stack = oldstack;
      } else if (scan->flags & INPUT_READY)
      {
/* there used to be this here...
            if (!(scan->lagged) && !(scan->flags & PERM_LAG))
   for reference... */

         if (!(scan->lagged))
         {
            current_player = scan;
            current_room = scan->location;
            input_for_one(scan);
            action = "processing players";
            current_player = 0;
            current_room = 0;

#ifdef PC
            if (scan->flags & PROMPT && scan == input_player)
#else
            if (scan->flags & PROMPT)
#endif
            {
               if (scan->saved_flags & CONVERSE)
                  do_prompt(scan, scan->converse_prompt);
               else
                  do_prompt(scan, scan->prompt);
            }
         }
         memset(scan->ibuffer, 0, IBUFFER_LENGTH);
         scan->flags &= ~INPUT_READY;
      }
   }
}