Exemple #1
0
static int check_lines()
{
    int i,j;
    int total = 0;
    int lines = 0;
    for(i = 0; i < 4; i++)
    {
        if(row+i < 20)
        {
            for(j = 0; j < 14; j++)
            {
                total += grid[row+i][j];
            }
        }
        if(total == 14)
        {
            lines++;
            copy_down(row+i, grid);
            trigger_event("LineCleared", (void*)row+i);
        }
        total = 0;
    }
    trigger_event("DoneClearing", (void*)row+i);
    return lines;
}
Exemple #2
0
static void new_block()
{
    row = 0;
    col = 6;
    rot = 0;
    type = next_type;
    next_type = rand()%7;
    trigger_event("NewBlock", (void*)next_type);
    if(check_move())
        trigger_event("GameOver", NULL);
}
Exemple #3
0
static void calc_score(int lines)
{
    score = score + lines*10 * level;
    type = rand()%7;
    trigger_event("NewScore", (void*)score);
    total_lines += lines;
    if(total_lines >= 10)
    {
        level++;
        total_lines = 0;
        trigger_event("NewLevel", (void*)level);
    }
}
Exemple #4
0
static int move(int dir)
{
    switch(dir)
    {
    case LEFT:
        col--;
        break;
    case RIGHT:
        col++;
        break;
    case DOWN:
        row++;
        break;
    case ROTATE:
        rot = (rot+1)%4;
        break;
    }
    int rc = check_move();
    if(rc == 1)
    {
        switch(dir)
        {
        case LEFT:
            col++;
            break;
        case RIGHT:
            col--;
            break;
        case DOWN:
            row--;
            break;
        case ROTATE:
            rot = rot == 0 ? 3 : rot-1;
            break;
        }
        if(dir == DOWN)
        {
            cement_block();
            trigger_event("BlockHit", NULL);
            int lines = check_lines();
            if(lines)
                calc_score(lines);
            new_block();
       }
    }
    else
    {
        trigger_event("MoveSucceeded", (void*)dir);
    }
    return rc;
}
Exemple #5
0
static void
service_instance_update(struct vlist_tree *tree, struct vlist_node *node_new,
			struct vlist_node *node_old)
{
	struct service_instance *in_o = NULL, *in_n = NULL;

	if (node_old)
		in_o = container_of(node_old, struct service_instance, node);

	if (node_new)
		in_n = container_of(node_new, struct service_instance, node);

	if (in_o && in_n) {
		DEBUG(2, "Update instance %s::%s\n", in_o->srv->name, in_o->name);
		instance_update(in_o, in_n);
		instance_free(in_n);
	} else if (in_o) {
		DEBUG(2, "Free instance %s::%s\n", in_o->srv->name, in_o->name);
		instance_stop(in_o);
		instance_free(in_o);
	} else if (in_n) {
		DEBUG(2, "Create instance %s::%s\n", in_n->srv->name, in_n->name);
		instance_start(in_n);
	}
	blob_buf_init(&b, 0);
	trigger_event("instance.update", b.head);
}
Exemple #6
0
/**
 * periodically called by the main memcache loop. This will connect zookeeper if
 * necessary. Also, if the generation has changed (because of a zookeeper even),
 * it will then trigger data processing.
 */
void mc_zookeeper_tick() {
    ticker++;

    if (!zh) {
        LOG_DEBUG(("Connecting zookeeper..."));
        zh = zookeeper_init(settings.zookeeper_connect, process, 30000, &myid, 0, 0);
        if (!zh) {
            LOG_INFO(("Could not connect to zookeeper, error: %d", errno));
        }
        else {
            LOG_DEBUG(("Zookeeper connection ok, status is %d", zoo_state(zh)));
        }
        trigger_event();
    }

    if (connected) {
        long current_generation = generation;
        if (last_generation < current_generation) {
            LOG_DEBUG(("Tick (%d)", ticker));
            int rc = zoo_aget_children(zh, settings.zookeeper_path, 1, node_completion, &ticker);
            if (rc != 0) {
                LOG_WARN(("Error %s while retrieving children!", zerror(rc)));
            }
            else {
                last_generation = current_generation;
            }
        }
    }
}
Exemple #7
0
/**
 * libevent handler for zookeeper events on the fd.
 */
static void zookeeper_event_handler(int fd, short event_type, void * arg)
{
    int event_flags = 0;

    if (event_type & EV_READ) {
        LOG_DEBUG((" -> READ"));
        event_flags |= ZOOKEEPER_READ;
    }
    if (event_type & EV_WRITE) {
        LOG_DEBUG((" -> WRITE"));
        event_flags |= ZOOKEEPER_WRITE;
    }

    if (event_flags) {
        if (zh) {
            zookeeper_process(zh, event_flags);
        }
        else {
            LOG_INFO(("Event handler called with zh == null!"));
        }
    }
    else {
        LOG_DEBUG(("Called from timeout!"));
    }

    trigger_event();
}
Exemple #8
0
/* Timer callback for @periodic_save_timer.  As explained in @install_timer,
 * this function must erase the expired timer ID from all variables.  */
static void
periodic_save_handler(void *xxx)
{
	static int periodic_save_event_id = EVENT_NONE;
	milliseconds_T interval;

	if (get_cmd_opt_bool((const unsigned char *)"anonymous")) return;

	/* Don't trigger anything at startup */
	if (periodic_save_event_id == EVENT_NONE)
		set_event_id(periodic_save_event_id, (unsigned char *)"periodic-saving");
	else
		trigger_event(periodic_save_event_id);

	interval = sec_to_ms(get_opt_int((const unsigned char *)"infofiles.save_interval", NULL));
	if (!interval) {
		/* We should get here only if @periodic_save_handler
		 * is being called from @periodic_save_change_hook or
		 * @init_timer, rather than from the timer system.  */
		assert(periodic_save_timer == TIMER_ID_UNDEF);
		return;
	}

	install_timer(&periodic_save_timer, interval, periodic_save_handler, NULL);
	/* The expired timer ID has now been erased.  */
}
Exemple #9
0
void init_logic()
{
    srand(time(NULL));
    type = rand()%7;
    next_type = rand()%7;
    int types[2];
    types[0] = type;
    types[1] = next_type;
    register_event_handler("AttemptMoveLeft", logic_AttemptMoveLeft);
    register_event_handler("AttemptMoveRight", logic_AttemptMoveRight);
    register_event_handler("AttemptMoveDown", logic_AttemptMoveDown);
    register_event_handler("BlockDrop", logic_BlockDrop);
    register_event_handler("AttemptBlockRotate", logic_AttemptBlockRotate);
    trigger_event("LogicReady", (void*)types);
    trigger_event("NewScore", 0);
    trigger_event("NewLevel", 1);
}
Exemple #10
0
	inline void	SoloScene::calculate_and_send_position()
	{
		TEXEngine::Core::Message	parameters(3,0,0);


		parameters.add_integral_data(0,static_cast<TEXEngine::Core::MESSAGE_INTEGRAL_DATA_TYPE>(get_id()));
		parameters.add_integral_data(1,static_cast<TEXEngine::Core::MESSAGE_INTEGRAL_DATA_TYPE>(0));
		parameters.add_integral_data(2,static_cast<TEXEngine::Core::MESSAGE_INTEGRAL_DATA_TYPE>(1));
		trigger_event(PLAYER_POSITION,parameters);
	}
Exemple #11
0
// ------------------------------------------------------------------------
// move the final step in the path
// ------------------------------------------------------------------------
void t_army_mover::finish_path()
{
	declare_timer( timer_1, "finish_path" );
	end_move();
	if (m_has_trigger || m_landing)
	{	
		////////////////////////////////////////////////////////////
		// replay functionality
		
		m_army->get_map()->record_look_trigger_event( m_army, m_trigger_point.direction );
		
		////////////////////////////////////////////////////////////
		
		m_army->turn_to( m_trigger_point.direction );
		
		if (m_army->get_position() != m_trigger_point)
		{
			assert( m_army->get_position() == m_trigger_point.last_point );
			expend_movement( m_trigger_point.move_cost );
		}
		redraw_windows();
		if (m_has_trigger) 
		{
			assert( !m_landing );
			declare_timer( timer_4, "Activate trigger" );
			trigger_event();
			activate_trigger();
		}
		else
		{
			assert( m_army->is_boat() );
			assert( m_landing );
			m_army->leave_boat( m_trigger_point );
			trigger_event();
		}
	}
	else
		trigger_event();
	on_end();
}
Exemple #12
0
//void udb_serial_callback_received_byte(uint8_t rxchar)
void mavlink_callback_received_byte(uint8_t rxchar)
{
//	DPRINT("%u \r\n", rxchar);

	if (mavlink_parse_char(0, rxchar, &msg[mavlink_message_index], &r_mavlink_status))
	{
		// Check that handling of previous message has completed before calling again
		if (handling_of_message_completed == true)
		{
			// Switch between incoming message buffers
			if (mavlink_message_index == 0) mavlink_message_index = 1;
			else mavlink_message_index = 0;
			handling_of_message_completed = false;
			trigger_event(mavlink_process_message_handle);
		}
	}
}
Exemple #13
0
// ------------------------------------------------------------------------
// class to move army on adventure map
// ------------------------------------------------------------------------
void t_army_mover::cancel_move()
{
	if (m_halted)
		return;

	t_counted_ptr<t_army_mover> ref = this;
	t_window_ptr				frame = m_window->get_frame();	// temporary reference to prevent the adventure frame
																// from removing itself if the game is over
	end_move();

	trigger_event();
	
	if (m_has_trigger && m_army->get_position() == m_trigger_point)
		activate_trigger();
	
	on_end();
}
Exemple #14
0
// ------------------------------------------------------------------------
// do movement that's hidden
// ------------------------------------------------------------------------
void t_army_mover::do_hidden_move()
{
	if (m_is_visible)
		return;
	if (m_path.size() == 0)
	{
		finish_path();
		return;
	}

	t_adventure_map const&  map = *m_army->get_map();
	t_player&				player = map.get_player();
	int						team = player.get_team();

	declare_timer( timer_1, "do_hidden_movement" );
	while (!m_is_visible && !m_halted)
	{
		t_adventure_path_point& point = m_path[m_step];

		m_army->move( point );
		expend_movement( point.move_cost );
		mark_eluded_armies();
		if (m_step == m_path.size() - 1)
		{
			finish_path();
			return;
		}
		trigger_event();
		if (m_halted) 
			return;
		m_is_visible = !m_army->hidden_by_fog_of_war( team ) && show_enemy_moves();
		if (m_is_visible)
			break; // break here, because start_new_square will increment step.
		++m_step;
		declare_timer( timer_2, "on_starting_new_square: hidden" );
		on_starting_new_square();
	}
	if (m_halted)
		return;
	m_army->set_action( k_adv_actor_action_walk );
	m_distance = compute_overall_distance( m_path, m_step + 1 );
	start_new_square();
	prepare_move( 0 );
	set_next_time( get_time() + get_delay() );
}
Exemple #15
0
struct uri *
get_proxy_uri(struct uri *uri, struct connection_state *error_state)
{
    if (uri->protocol == PROTOCOL_PROXY) {
        return get_composed_uri(uri, URI_BASE);
    } else {
#ifdef CONFIG_SCRIPTING
        unsigned char *tmp = NULL;
        static int get_proxy_event_id = EVENT_NONE;

        set_event_id(get_proxy_event_id, "get-proxy");
        trigger_event(get_proxy_event_id, &tmp, struri(uri));

        uri = get_proxy_worker(uri, tmp, error_state);
        mem_free_if(tmp);
        return uri;
#else
        return get_proxy_worker(uri, NULL, error_state);
#endif
    }
}
Exemple #16
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);
	}
}
// Low priority service routine trigger
inline void data_services_trigger(void)
{
	trigger_event(data_service_event_handle);
}
			void	PSPControllerDevice::update( const unsigned long id )
			{
				Core::Message	parameters(5,0,0);
				int				difference_x = 0;
				int				difference_y = 0;
		
		
		
				parameters.add_integral_data(0,id);
				parameters.add_integral_data(2,0);
				memcpy(&this->_previous_button_state,&this->_current_button_state,sizeof(SceCtrlData));
				sceCtrlPeekBufferPositive(&this->_current_button_state,1);


				parameters.add_integral_data(3,static_cast<Core::MESSAGE_INTEGRAL_DATA_TYPE>(this->_current_button_state.Lx));
				parameters.add_integral_data(4,static_cast<Core::MESSAGE_INTEGRAL_DATA_TYPE>(this->_current_button_state.Ly));
				trigger_event(Core::PSP_CONTROLLER_STICK_POSITION,parameters);


				difference_x = this->_current_button_state.Lx - this->_previous_button_state.Lx; 
				difference_y = this->_current_button_state.Ly - this->_previous_button_state.Ly;
			
				if ( std::abs(difference_x) > _deadzone  ||  std::abs(difference_y) > _deadzone )
				{
					parameters.add_integral_data(3,static_cast<Core::MESSAGE_INTEGRAL_DATA_TYPE>(difference_x));
					parameters.add_integral_data(4,static_cast<Core::MESSAGE_INTEGRAL_DATA_TYPE>(difference_y));
					trigger_event(Core::PSP_CONTROLLER_STICK_POSITION_CHANGED,parameters);
				}

				if ( this->_current_button_state.Buttons != this->_previous_button_state.Buttons )
				{
					int	select = (this->_current_button_state.Buttons & SCE_CTRL_SELECT)  - (this->_previous_button_state.Buttons & SCE_CTRL_SELECT);
					int	start = (this->_current_button_state.Buttons & SCE_CTRL_START) - (this->_previous_button_state.Buttons & SCE_CTRL_START);
					int	up = (this->_current_button_state.Buttons & SCE_CTRL_UP) -( this->_previous_button_state.Buttons & SCE_CTRL_UP);
					int	right = (this->_current_button_state.Buttons & SCE_CTRL_RIGHT) - (this->_previous_button_state.Buttons & SCE_CTRL_RIGHT);
					int	down = (this->_current_button_state.Buttons & SCE_CTRL_DOWN) - (this->_previous_button_state.Buttons & SCE_CTRL_DOWN);
					int	left = (this->_current_button_state.Buttons & SCE_CTRL_LEFT) - (this->_previous_button_state.Buttons & SCE_CTRL_LEFT);
					int	L = (this->_current_button_state.Buttons & SCE_CTRL_L) - (this->_previous_button_state.Buttons & SCE_CTRL_L);
					int	R = (this->_current_button_state.Buttons & SCE_CTRL_R) - (this->_previous_button_state.Buttons & SCE_CTRL_R);
					int	triangle = (this->_current_button_state.Buttons & SCE_CTRL_TRIANGLE) - (this->_previous_button_state.Buttons & SCE_CTRL_TRIANGLE);
					int	circle = (this->_current_button_state.Buttons & SCE_CTRL_CIRCLE) - (this->_previous_button_state.Buttons & SCE_CTRL_CIRCLE);
					int	cross = (this->_current_button_state.Buttons & SCE_CTRL_CROSS) - (this->_previous_button_state.Buttons & SCE_CTRL_CROSS);
					int	square= (this->_current_button_state.Buttons & SCE_CTRL_SQUARE) - (this->_previous_button_state.Buttons & SCE_CTRL_SQUARE);



					parameters.add_integral_data(3,0);
					parameters.add_integral_data(4,0);
					if ( select < 0 )
						trigger_event(Core::PSP_CONTROLLER_SELECT_UP,parameters);
					else if ( select > 0 )
						trigger_event(Core::PSP_CONTROLLER_SELECT_DOWN,parameters);

					if ( start < 0 )
						trigger_event(Core::PSP_CONTROLLER_START_UP,parameters);
					else if ( start > 0 )
						trigger_event(Core::PSP_CONTROLLER_START_DOWN,parameters);

					if ( up < 0 )
						trigger_event(Core::PSP_CONTROLLER_UPARROW_UP,parameters);
					else if ( up > 0 )
						trigger_event(Core::PSP_CONTROLLER_UPARROW_DOWN,parameters);

					if ( right < 0 )
						trigger_event(Core::PSP_CONTROLLER_RIGHTARROW_UP,parameters);
					else if ( right > 0 )
						trigger_event(Core::PSP_CONTROLLER_RIGHTARROW_DOWN,parameters);

					if ( down < 0 )
						trigger_event(Core::PSP_CONTROLLER_DOWNARROW_UP,parameters);
					else if ( down > 0 )
						trigger_event(Core::PSP_CONTROLLER_DOWNARROW_DOWN,parameters);

					if ( left < 0 )
						trigger_event(Core::PSP_CONTROLLER_LEFTARROW_UP,parameters);
					else if ( left > 0 )
						trigger_event(Core::PSP_CONTROLLER_LEFTARROW_DOWN,parameters);

					if ( L < 0 )
						trigger_event(Core::PSP_CONTROLLER_LEFTTRIGGER_UP,parameters);
					else if ( L > 0 )
						trigger_event(Core::PSP_CONTROLLER_LEFTTRIGGER_DOWN,parameters);
			
					if ( R < 0 )
						trigger_event(Core::PSP_CONTROLLER_RIGHTTRIGGER_UP,parameters);
					else if ( R > 0 )
						trigger_event(Core::PSP_CONTROLLER_RIGHTTRIGGER_DOWN,parameters);

					if ( triangle < 0 )
						trigger_event(Core::PSP_CONTROLLER_TRIANGLE_UP,parameters);
					else if ( triangle > 0 )
						trigger_event(Core::PSP_CONTROLLER_TRIANGLE_DOWN,parameters);

					if ( circle < 0 )
						trigger_event(Core::PSP_CONTROLLER_CIRCLE_UP,parameters);
					else if ( circle > 0 )
						trigger_event(Core::PSP_CONTROLLER_CIRCLE_DOWN,parameters);

					if ( cross < 0 )
						trigger_event(Core::PSP_CONTROLLER_CROSS_UP,parameters);
					else if ( cross > 0 )
						trigger_event(Core::PSP_CONTROLLER_CROSS_DOWN,parameters);

					if ( square < 0 )
						trigger_event(Core::PSP_CONTROLLER_SQUARE_UP,parameters);
					else if ( square > 0 )
						trigger_event(Core::PSP_CONTROLLER_SQUARE_DOWN,parameters);
				}
			};
Exemple #19
0
/**
 * Op throws any object toss_item.
 * @param op Living thing throwing something.
 * @param toss_item Item thrown.
 * @param dir Direction to throw. */
void do_throw(object *op, object *toss_item, int dir)
{
	object *left_cont, *throw_ob = toss_item, *left = NULL, *tmp_op;
	tag_t left_tag;
	rv_vector range_vector;

	if (!throw_ob)
	{
		if (op->type == PLAYER)
		{
			new_draw_info(NDI_UNIQUE, op, "You have nothing to throw.");
		}

		return;
	}

	if (QUERY_FLAG(throw_ob, FLAG_STARTEQUIP))
	{
		if (op->type == PLAYER)
		{
			new_draw_info(NDI_UNIQUE, op, "The gods won't let you throw that.");
		}

		return;
	}

	if (throw_ob->weight <= 0)
	{
		new_draw_info_format(NDI_UNIQUE, op, "You can't throw %s.\n", query_base_name(throw_ob, NULL));
		return;
	}

	/* These are throwing objects left to the player */
	left = throw_ob;
	left_cont = left->env;
	left_tag = left->count;

	/* Sometimes get_split_ob can't split an object (because op->nrof==0?)
	 * and returns NULL. We must use 'left' then */
	if ((throw_ob = get_split_ob(throw_ob, 1, NULL, 0)) == NULL)
	{
		throw_ob = left;
		remove_ob(left);
		check_walk_off(left, NULL, MOVE_APPLY_VANISHED);

		if (op->type == PLAYER)
		{
			esrv_del_item(CONTR(op), left->count, left->env);
		}
	}
	else if (op->type == PLAYER)
	{
		if (was_destroyed(left, left_tag))
		{
			esrv_del_item(CONTR(op), left_tag, left_cont);
		}
		else
		{
			esrv_update_item(UPD_NROF, op, left);
		}
	}

	/* Special case: throwing powdery substances like dust, dirt */
	if (QUERY_FLAG(throw_ob, FLAG_DUST))
	{
		cast_dust(op, throw_ob, dir);

		/* update the shooting speed for the player action timer.
		 * We init the used skill with it - its not calculated here.
		 * cast_dust() can change the used skill... */
		if (op->type == PLAYER)
		{
			op->chosen_skill->stats.maxsp = throw_ob->last_grace;
		}

		return;
	}

	/* Targetting throwing */
	if (!dir && op->type == PLAYER && OBJECT_VALID(CONTR(op)->target_object, CONTR(op)->target_object_count))
	{
		dir = get_dir_to_target(op, CONTR(op)->target_object, &range_vector);
	}

	/* Three things here prevent a throw, you aimed at your feet, you
	 * have no effective throwing strength, or you threw at a wall */
	if (!dir || wall(op->map, op->x + freearr_x[dir], op->y + freearr_y[dir]))
	{
		/* Bounces off 'wall', and drops to feet */
		if (!QUERY_FLAG(throw_ob, FLAG_REMOVED))
		{
			remove_ob(throw_ob);

			if (check_walk_off(throw_ob, NULL, MOVE_APPLY_MOVE) != CHECK_WALK_OK)
			{
				return;
			}
		}

		throw_ob->x = op->x;
		throw_ob->y = op->y;

		if (!insert_ob_in_map(throw_ob, op->map, op, 0))
		{
			return;
		}

		if (op->type == PLAYER)
		{
			if (!dir)
			{
				new_draw_info_format(NDI_UNIQUE, op, "You drop %s at the ground.", query_name(throw_ob, NULL));
			}
			else
			{
				new_draw_info(NDI_UNIQUE, op, "Something is in the way.");
			}
		}

		return;
	}

	set_owner(throw_ob, op);
	set_owner(throw_ob->inv, op);
	throw_ob->direction = dir;
	throw_ob->x = op->x;
	throw_ob->y = op->y;

	/* Save original wc and dam */
	throw_ob->last_heal = throw_ob->stats.wc;
	throw_ob->stats.hp = throw_ob->stats.dam;

	/* Speed */
	throw_ob->speed = MIN(1.0f, (speed_bonus[op->stats.Str] + 1.0f) / 1.5f);

	/* Now we get the wc from the used skill. */
	if ((tmp_op = SK_skill(op)))
	{
		throw_ob->stats.wc += tmp_op->last_heal;
	}
	/* Monsters */
	else
	{
		throw_ob->stats.wc += 10;
	}

	throw_ob->stats.wc_range = op->stats.wc_range;

	if (QUERY_FLAG(throw_ob, FLAG_IS_THROWN))
	{
		throw_ob->stats.dam += throw_ob->magic;
		throw_ob->stats.wc += throw_ob->magic;

		/* Adjust for players */
		if (op->type == PLAYER)
		{
			op->chosen_skill->stats.maxsp = throw_ob->last_grace;
			throw_ob->stats.dam = FABS((int) ((float) (throw_ob->stats.dam + dam_bonus[op->stats.Str] / 2) * LEVEL_DAMAGE(SK_level(op))));
			throw_ob->stats.wc += thaco_bonus[op->stats.Dex] + SK_level(op);
		}
		else
		{
			throw_ob->stats.dam = FABS((int) ((float) (throw_ob->stats.dam) * LEVEL_DAMAGE(op->level)));
			throw_ob->stats.wc += 10 + op->level;
		}

		throw_ob->stats.grace = throw_ob->last_sp;
		throw_ob->stats.maxgrace = 60 + (RANDOM() % 12);

		/* Only throw objects get directional faces */
		if (GET_ANIM_ID(throw_ob) && NUM_ANIMATIONS(throw_ob))
		{
			SET_ANIMATION(throw_ob, (NUM_ANIMATIONS(throw_ob) / NUM_FACINGS(throw_ob)) * dir);
		}

		/* Adjust damage with item condition */
		throw_ob->stats.dam = (sint16) (((float) throw_ob->stats.dam / 100.0f) * (float) throw_ob->item_condition);
	}

	if (throw_ob->stats.dam < 0)
	{
		throw_ob->stats.dam = 0;
	}

	update_ob_speed(throw_ob);
	throw_ob->speed_left = 0;

	SET_MULTI_FLAG(throw_ob, FLAG_FLYING);
	SET_FLAG(throw_ob, FLAG_FLY_ON);
	SET_FLAG(throw_ob, FLAG_WALK_ON);

	play_sound_map(op->map, CMD_SOUND_EFFECT, "throw.ogg", op->x, op->y, 0, 0);

	/* Trigger the THROW event */
	trigger_event(EVENT_THROW, op, throw_ob, NULL, NULL, 0, 0, 0, SCRIPT_FIX_ACTIVATOR);

	if (insert_ob_in_map(throw_ob, op->map, op, 0))
	{
		move_arrow(throw_ob);
	}
}
Exemple #20
0
/**
 * 'victim' moves onto 'trap' (trap has FLAG_WALK_ON or FLAG_FLY_ON set) or
 * 'victim' leaves 'trap' (trap has FLAG_WALK_OFF or FLAG_FLY_OFF) set.
 *
 * I added the flags parameter to give the single events more information
 * about whats going on:
 *
 * Most important is the "MOVE_APPLY_VANISHED" flag.
 * If set, a object has left a tile but "vanished" and not moved (perhaps
 * it exploded or something). This means that some events are not
 * triggered like trapdoors or teleporter traps for example which have a
 * "FLY/MOVE_OFF" set. This will avoid that they touch invalid objects.
 * @param trap Object victim moved on.
 * @param victim The object that moved on trap.
 * @param originator Player, monster or other object that caused 'victim'
 * to move onto 'trap'. Will receive messages caused by this action. May
 * be NULL, however, some types of traps require an originator to
 * function.
 * @param flags Flags. */
void move_apply(object *trap, object *victim, object *originator, int flags)
{
	static int recursion_depth = 0;

	/* move_apply() is the most likely candidate for causing unwanted and
	 * possibly unlimited recursion. */
	/* The following was changed because it was causing perfeclty correct
	 * maps to fail.  1)  it's not an error to recurse:
	 * rune detonates, summoning monster.  monster lands on nearby rune.
	 * nearby rune detonates.  This sort of recursion is expected and
	 * proper.  This code was causing needless crashes. */
	if (recursion_depth >= 500)
	{
		LOG(llevDebug, "WARNING: move_apply(): aborting recursion [trap arch %s, name %s; victim arch %s, name %s]\n", trap->arch->name, trap->name, victim->arch->name, victim->name);
		return;
	}

	if (trap->head)
	{
		trap = trap->head;
	}

	/* Trigger the TRIGGER event */
	if (trigger_event(EVENT_TRIGGER, victim, trap, originator, NULL, 0, 0, 0, SCRIPT_FIX_NOTHING))
	{
		return;
	}

	recursion_depth++;

	switch (trap->type)
	{
		/* these objects can trigger other objects connected to them.
		 * We need to check them at map loading time and other special
		 * events to be sure to have a 100% working map state. */
		case BUTTON:
		case PEDESTAL:
			update_button(trap);
			break;

		case TRIGGER_BUTTON:
		case TRIGGER_PEDESTAL:
		case TRIGGER_ALTAR:
			check_trigger(trap, victim);
			break;

		case CHECK_INV:
			check_inv(victim, trap);
			break;

		/* these objects trigger to but they are "instant".
		 * We don't need to check them when loading. */
		case ALTAR:
			/* sacrifice victim on trap */
			apply_altar(trap, victim, originator);
			break;

		case CONVERTER:
			if (!(flags & MOVE_APPLY_VANISHED))
			{
				convert_item(victim, trap);
			}

			break;

		case PLAYERMOVER:
			break;

		/* should be walk_on/fly_on only */
		case SPINNER:
			if (victim->direction)
			{
				if ((victim->direction = victim->direction + trap->direction) > 8)
				{
					victim->direction = (victim->direction % 8) + 1;
				}

				update_turn_face(victim);
			}

			break;

		case DIRECTOR:
			if (victim->direction)
			{
				victim->direction = trap->direction;
				update_turn_face(victim);
			}

			break;

		/* no need to hit anything */
		case MMISSILE:
			if (IS_LIVE(victim) && !(flags&MOVE_APPLY_VANISHED))
			{
				tag_t trap_tag = trap->count;
				hit_player(victim, trap->stats.dam, trap, AT_MAGIC);

				if (!was_destroyed(trap, trap_tag))
				{
					remove_ob(trap);
				}

				check_walk_off(trap, NULL, MOVE_APPLY_VANISHED);
			}

			break;

		case THROWN_OBJ:
			if (trap->inv == NULL || (flags & MOVE_APPLY_VANISHED))
			{
				break;
			}

		/* fallthrough */
		case ARROW:
			/* bad bug: monster throw a object, make a step forwards, step on object ,
			 * trigger this here and get hit by own missile - and will be own enemy.
			 * Victim then is his own enemy and will start to kill herself (this is
			 * removed) but we have not synced victim and his missile. To avoid senseless
			 * action, we avoid hits here */
			if ((IS_LIVE(victim) && trap->speed) && trap->owner != victim)
			{
				hit_with_arrow(trap, victim);
			}

			break;

		case CONE:
		case LIGHTNING:
			break;

		case BULLET:
			if ((QUERY_FLAG(victim, FLAG_NO_PASS) || IS_LIVE(victim)) && !(flags & MOVE_APPLY_VANISHED))
			{
				check_fired_arch(trap);
			}

			break;

		case TRAPDOOR:
		{
			int max, sound_was_played;
			object *ab;

			if ((flags & MOVE_APPLY_VANISHED))
			{
				break;
			}

			if (!trap->value)
			{
				sint32 tot;

				for (ab = trap->above, tot = 0; ab != NULL; ab = ab->above)
				{
					if (!QUERY_FLAG(ab, FLAG_FLYING))
					{
						tot += (ab->nrof ? ab->nrof : 1) * ab->weight + ab->carrying;
					}
				}

				if (!(trap->value = (tot > trap->weight) ? 1 : 0))
				{
					break;
				}

				SET_ANIMATION(trap, (NUM_ANIMATIONS(trap) / NUM_FACINGS(trap)) * trap->direction + trap->value);
				update_object(trap, UP_OBJ_FACE);
			}

			for (ab = trap->above, max = 100, sound_was_played = 0; --max && ab && !QUERY_FLAG(ab, FLAG_FLYING); ab = ab->above)
			{
				if (!sound_was_played)
				{
					play_sound_map(trap->map, trap->x, trap->y, SOUND_FALL_HOLE, SOUND_NORMAL);
					sound_was_played = 1;
				}

				if (ab->type == PLAYER)
				{
					new_draw_info(NDI_UNIQUE, ab, "You fall into a trapdoor!");
				}

				transfer_ob(ab, EXIT_X(trap), EXIT_Y(trap), trap->last_sp, ab, trap);
			}

			break;
		}


		case PIT:
			/* Pit not open? */
			if ((flags & MOVE_APPLY_VANISHED) || trap->stats.wc > 0)
			{
				break;
			}

			play_sound_map(victim->map, victim->x, victim->y, SOUND_FALL_HOLE, SOUND_NORMAL);

			if (victim->type == PLAYER)
			{
				new_draw_info(NDI_UNIQUE, victim, "You fall through the hole!\n");
			}

			transfer_ob(victim->head ? victim->head : victim, EXIT_X(trap), EXIT_Y(trap), trap->last_sp, victim, trap);

			break;

		case EXIT:
			/* If no map path specified, we assume it is the map path of the exit. */
			if (!EXIT_PATH(trap))
			{
				FREE_AND_ADD_REF_HASH(EXIT_PATH(trap), trap->map->path);
			}

			if (!(flags & MOVE_APPLY_VANISHED) && victim->type == PLAYER && EXIT_PATH(trap) && EXIT_Y(trap) != -1 && EXIT_X(trap) != -1)
			{
				/* Basically, don't show exits leading to random maps the players output. */
				if (trap->msg && strncmp(EXIT_PATH(trap), "/!", 2) && strncmp(EXIT_PATH(trap), "/random/", 8))
				{
					new_draw_info(NDI_NAVY, victim, trap->msg);
				}

				enter_exit(victim, trap);
			}

			break;

		case SHOP_MAT:
			if (!(flags & MOVE_APPLY_VANISHED))
			{
				apply_shop_mat(trap, victim);
			}

			break;

		/* Drop a certain amount of gold, and have one item identified */
		case IDENTIFY_ALTAR:
			if (!(flags & MOVE_APPLY_VANISHED))
			{
				apply_identify_altar(victim, trap, originator);
			}

			break;

		case SIGN:
			/* Only player should be able read signs */
			if (victim->type == PLAYER)
			{
				apply_sign(victim, trap);
			}

			break;

		case CONTAINER:
			if (victim->type == PLAYER)
			{
				(void) esrv_apply_container(victim, trap);
			}

			break;

		case RUNE:
			if (!(flags & MOVE_APPLY_VANISHED) && trap->level && IS_LIVE(victim))
			{
				spring_trap(trap, victim);
			}

			break;

#if 0
		/* we don't have this atm. */
		case DEEP_SWAMP:
			if (!(flags & MOVE_APPLY_VANISHED))
			{
				walk_on_deep_swamp(trap, victim);
			}

			break;
#endif

		default:
			LOG(llevDebug, "name %s, arch %s, type %d with fly/walk on/off not handled in move_apply()\n", trap->name, trap->arch->name, trap->type);
			break;
	}

	recursion_depth--;
}
Exemple #21
0
/**
 * Main apply handler.
 *
 * Checks for unpaid items before applying.
 * @param op ::object causing tmp to be applied.
 * @param tmp ::object being applied.
 * @param aflag Special (always apply/unapply) flags. Nothing is done
 * with them in this function - they are passed to apply_special().
 * @retval 0 Player or monster can't apply objects of that type.
 * @retval 1 Has been applied, or there was an error applying the object.
 * @retval 2 Objects of that type can't be applied if not in
 * inventory. */
int manual_apply(object *op, object *tmp, int aflag)
{
	if (tmp->head)
	{
		tmp = tmp->head;
	}

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

	if (QUERY_FLAG(tmp, FLAG_UNPAID) && !QUERY_FLAG(tmp, FLAG_APPLIED))
	{
		if (op->type == PLAYER)
		{
			new_draw_info(NDI_UNIQUE, op, "You should pay for it first.");
			return 1;
		}
		/* Monsters just skip unpaid items */
		else
		{
			return 0;
		}
	}

	/* Monsters must not apply random chests, nor magic_mouths with a counter */
	if (op->type != PLAYER && tmp->type == TREASURE)
	{
		return 0;
	}

	/* Trigger the APPLY event */
	if (!(aflag & AP_NO_EVENT) && trigger_event(EVENT_APPLY, op, tmp, NULL, NULL, aflag, 0, 0, SCRIPT_FIX_ACTIVATOR))
	{
		return 1;
	}

	aflag &= ~AP_NO_EVENT;

	/* Control apply by controling a set exp object level or player exp level */
	if (tmp->item_level)
	{
		int tmp_lev;

		if (tmp->item_skill)
		{
			tmp_lev = find_skill_exp_level(op, tmp->item_skill);
		}
		else
		{
			tmp_lev = op->level;
		}

		if (tmp->item_level > tmp_lev)
		{
			new_draw_info(NDI_UNIQUE, op, "The item level is too high to apply.");
			return 1;
		}
	}

	switch (tmp->type)
	{
		case HOLY_ALTAR:
			new_draw_info_format(NDI_UNIQUE, op, "You touch the %s.", tmp->name);

			if (change_skill(op, SK_PRAYING))
			{
				pray_at_altar(op, tmp);
			}
			else
			{
				new_draw_info(NDI_UNIQUE, op, "Nothing happens. It seems you miss the right skill.");
			}

			return 1;
			break;

		case HANDLE:
			new_draw_info(NDI_UNIQUE, op, "You turn the handle.");
			play_sound_map(op->map, op->x, op->y, SOUND_TURN_HANDLE, SOUND_NORMAL);
			tmp->value = tmp->value ? 0 : 1;
			SET_ANIMATION(tmp, ((NUM_ANIMATIONS(tmp) / NUM_FACINGS(tmp)) * tmp->direction) + tmp->value);
			update_object(tmp, UP_OBJ_FACE);
			push_button(tmp);

			return 1;

		case TRIGGER:
			if (check_trigger(tmp, op))
			{
				new_draw_info(NDI_UNIQUE, op, "You turn the handle.");
				play_sound_map(tmp->map, tmp->x, tmp->y, SOUND_TURN_HANDLE, SOUND_NORMAL);
			}
			else
			{
				new_draw_info(NDI_UNIQUE, op, "The handle doesn't move.");
			}

			return 1;

		case EXIT:
			if (op->type != PLAYER || !tmp->map)
			{
				return 0;
			}

			/* If no map path specified, we assume it is the map path of the exit. */
			if (!EXIT_PATH(tmp))
			{
				FREE_AND_ADD_REF_HASH(EXIT_PATH(tmp), tmp->map->path);
			}

			if (!EXIT_PATH(tmp) || !is_legal_2ways_exit(op, tmp) || (EXIT_Y(tmp) == -1 && EXIT_X(tmp) == -1))
			{
				new_draw_info_format(NDI_UNIQUE, op, "The %s is closed.", query_name(tmp, NULL));
			}
			else
			{
				/* Don't display messages for random maps. */
				if (tmp->msg && strncmp(EXIT_PATH(tmp), "/!", 2) && strncmp(EXIT_PATH(tmp), "/random/", 8))
				{
					new_draw_info(NDI_NAVY, op, tmp->msg);
				}

				enter_exit(op, tmp);
			}

			return 1;

		case SIGN:
			apply_sign(op, tmp);
			return 1;

		case BOOK:
			if (op->type == PLAYER)
			{
				apply_book(op, tmp);
				return 1;
			}

			return 0;

		case SKILLSCROLL:
			if (op->type == PLAYER)
			{
				apply_skillscroll(op, tmp);
				return 1;
			}

			return 0;

		case SPELLBOOK:
			if (op->type == PLAYER)
			{
				apply_spellbook(op, tmp);
				return 1;
			}

			return 0;

		case SCROLL:
			apply_scroll(op, tmp);
			return 1;

		case POTION:
			(void) apply_potion(op, tmp);
			return 1;

		case LIGHT_APPLY:
			apply_player_light(op, tmp);
			return 1;

		case LIGHT_REFILL:
			apply_player_light_refill(op, tmp);
			return 1;

		/* Eneq(@csd.uu.se): Handle apply on containers. */
		case CLOSE_CON:
			if (op->type == PLAYER)
			{
				(void) esrv_apply_container(op, tmp->env);
			}

			return 1;

		case CONTAINER:
			if (op->type == PLAYER)
			{
				(void) esrv_apply_container(op, tmp);
			}

			return 1;

		case TREASURE:
			apply_treasure(op, tmp);
			return 1;

		case WEAPON:
		case ARMOUR:
		case BOOTS:
		case GLOVES:
		case AMULET:
		case GIRDLE:
		case BRACERS:
		case SHIELD:
		case HELMET:
		case RING:
		case CLOAK:
		case WAND:
		case ROD:
		case HORN:
		case SKILL:
		case BOW:
		case SKILL_ITEM:
			/* Not in inventory */
			if (tmp->env != op)
			{
				return 2;
			}

			(void) apply_special(op, tmp, aflag);
			return 1;

		case DRINK:
		case FOOD:
		case FLESH:
			apply_food(op, tmp);
			return 1;

		case POISON:
			apply_poison(op, tmp);
			return 1;

		case SAVEBED:
			if (op->type == PLAYER)
			{
				apply_savebed(op);
				return 1;
			}

			return 0;

		case ARMOUR_IMPROVER:
			if (op->type == PLAYER)
			{
				apply_armour_improver(op, tmp);
				return 1;
			}

			return 0;

		case WEAPON_IMPROVER:
			apply_weapon_improver(op, tmp);
			return 1;

		case CLOCK:
			if (op->type == PLAYER)
			{
				timeofday_t tod;

				get_tod(&tod);
				new_draw_info_format(NDI_UNIQUE, op, "It is %d minute%s past %d o'clock %s", tod.minute + 1, ((tod.minute + 1 < 2) ? "" : "s"), ((tod.hour % (HOURS_PER_DAY / 2) == 0) ? (HOURS_PER_DAY / 2) : ((tod.hour) % (HOURS_PER_DAY / 2))), ((tod.hour >= (HOURS_PER_DAY / 2)) ? "pm" : "am"));
				return 1;
			}

			return 0;

		case POWER_CRYSTAL:
			apply_power_crystal(op, tmp);
			return 1;

		/* For lighting torches/lanterns/etc */
		case LIGHTER:
			if (op->type == PLAYER)
			{
				apply_lighter(op, tmp);
				return 1;
			}

			return 0;

		/* So the below default case doesn't execute for these objects,
		 * even if they have message. */
		case DOOR:
			return 0;

		/* Nothing from the above... but show a message if it has one. */
		default:
			if (tmp->msg)
			{
				new_draw_info(NDI_UNIQUE, op, tmp->msg);
				return 1;
			}

			return 0;
	}
}
Exemple #22
0
void create() 
{ 
	seteuid(getuid()); 
	message("channel:sys", HIR"【自然奇观】峨嵋金顶日出。\n"NOR, users());
	trigger_event();
}
Exemple #23
0
isc_result_t omapi_one_dispatch (omapi_object_t *wo,
				 struct timeval *t)
{
	fd_set r, w, x, rr, ww, xx;
	int max = 0;
	int count;
	int desc;
	struct timeval now, to;
	omapi_io_object_t *io, *prev, *next;
	omapi_waiter_object_t *waiter;
	omapi_object_t *tmp = (omapi_object_t *)0;
	isc_result_t status;

	if (!wo || wo -> type != omapi_type_waiter)
		waiter = (omapi_waiter_object_t *)0;
	else
		waiter = (omapi_waiter_object_t *)wo;

	FD_ZERO (&x);

	/* First, see if the timeout has expired, and if so return. */
	if (t) {
		gettimeofday (&now, (struct timezone *)0);
		cur_tv.tv_sec = now.tv_sec;
		cur_tv.tv_usec = now.tv_usec;
		if (now.tv_sec > t -> tv_sec ||
		    (now.tv_sec == t -> tv_sec && now.tv_usec >= t -> tv_usec))
			return ISC_R_TIMEDOUT;
			
		/* We didn't time out, so figure out how long until
		   we do. */
		to.tv_sec = t -> tv_sec - now.tv_sec;
		to.tv_usec = t -> tv_usec - now.tv_usec;
		if (to.tv_usec < 0) {
			to.tv_usec += 1000000;
			to.tv_sec--;
		}

		/* It is possible for the timeout to get set larger than
		   the largest time select() is willing to accept.
		   Restricting the timeout to a maximum of one day should
		   work around this.  -DPN.  (Ref: Bug #416) */
		if (to.tv_sec > (60 * 60 * 24))
			to.tv_sec = 60 * 60 * 24;
	}
	
	/* If the object we're waiting on has reached completion,
	   return now. */
	if (waiter && waiter -> ready)
		return ISC_R_SUCCESS;
	
      again:
	/* If we have no I/O state, we can't proceed. */
	if (!(io = omapi_io_states.next))
		return ISC_R_NOMORE;

	/* Set up the read and write masks. */
	FD_ZERO (&r);
	FD_ZERO (&w);

	for (; io; io = io -> next) {
		/* Check for a read socket.   If we shouldn't be
		   trying to read for this I/O object, either there
		   won't be a readfd function, or it'll return -1. */
		if (io -> readfd && io -> inner &&
		    (desc = (*(io -> readfd)) (io -> inner)) >= 0) {
			FD_SET (desc, &r);
			if (desc > max)
				max = desc;
		}
		
		/* Same deal for write fdets. */
		if (io -> writefd && io -> inner &&
		    (desc = (*(io -> writefd)) (io -> inner)) >= 0) {
			FD_SET (desc, &w);
			if (desc > max)
				max = desc;
		}
	}

	/* poll if all reader are dry */ 
	now.tv_sec = 0;
	now.tv_usec = 0;
	rr=r; 
	ww=w; 
	xx=x;

	/* poll once */
	count = select(max + 1, &r, &w, &x, &now);
	if (!count) {  
		/* We are dry now */ 
		trigger_event(&rw_queue_empty);
		/* Wait for a packet or a timeout... XXX */
		r = rr;
		w = ww;
		x = xx;
		count = select(max + 1, &r, &w, &x, t ? &to : NULL);
	}

	/* Get the current time... */
	gettimeofday (&cur_tv, (struct timezone *)0);

	/* We probably have a bad file descriptor.   Figure out which one.
	   When we find it, call the reaper function on it, which will
	   maybe make it go away, and then try again. */
	if (count < 0) {
		struct timeval t0;
		omapi_io_object_t *prev = (omapi_io_object_t *)0;
		io = (omapi_io_object_t *)0;
		if (omapi_io_states.next)
			omapi_io_reference (&io, omapi_io_states.next, MDL);

		while (io) {
			omapi_object_t *obj;
			FD_ZERO (&r);
			FD_ZERO (&w);
			t0.tv_sec = t0.tv_usec = 0;

			if (io -> readfd && io -> inner &&
			    (desc = (*(io -> readfd)) (io -> inner)) >= 0) {
			    FD_SET (desc, &r);
			    count = select (desc + 1, &r, &w, &x, &t0);
			   bogon:
			    if (count < 0) {
				log_error ("Bad descriptor %d.", desc);
				for (obj = (omapi_object_t *)io;
				     obj -> outer;
				     obj = obj -> outer)
					;
				for (; obj; obj = obj -> inner) {
				    omapi_value_t *ov;
				    int len;
				    const char *s;
				    ov = (omapi_value_t *)0;
				   status = omapi_get_value_str (obj,
							 (omapi_object_t *)0,
							 "name", &ov);
				   if(status!=ISC_R_SUCCESS){
						log_error("omapi_get_value_str failed!\n");
				   }
				    if (ov && ov -> value &&
					(ov -> value -> type ==
					 omapi_datatype_string)) {
					s = (char *)
						ov -> value -> u.buffer.value;
					len = ov -> value -> u.buffer.len;
				    } else {
					s = "";
					len = 0;
				    }
				    log_error ("Object %lx %s%s%.*s",
					       (unsigned long)obj,
					       obj -> type -> name,
					       len ? " " : "",
					       len, s);
				    if (len)
					omapi_value_dereference (&ov, MDL);
				}
				(*(io -> reaper)) (io -> inner);
				if (prev) {
				    omapi_io_dereference (&prev -> next, MDL);
				    if (io -> next)
					omapi_io_reference (&prev -> next,
							    io -> next, MDL);
				} else {
				    omapi_io_dereference
					    (&omapi_io_states.next, MDL);
				    if (io -> next)
					omapi_io_reference
						(&omapi_io_states.next,
						 io -> next, MDL);
				}
				omapi_io_dereference (&io, MDL);
				goto again;
			    }
			}
			
			FD_ZERO (&r);
			FD_ZERO (&w);
			t0.tv_sec = t0.tv_usec = 0;

			/* Same deal for write fdets. */
			if (io -> writefd && io -> inner &&
			    (desc = (*(io -> writefd)) (io -> inner)) >= 0) {
				FD_SET (desc, &w);
				count = select (desc + 1, &r, &w, &x, &t0);
				if (count < 0)
					goto bogon;
			}
			if (prev)
				omapi_io_dereference (&prev, MDL);
			omapi_io_reference (&prev, io, MDL);
			omapi_io_dereference (&io, MDL);
			if (prev -> next)
			    omapi_io_reference (&io, prev -> next, MDL);
		}
		if (prev)
			omapi_io_dereference (&prev, MDL);
		
	}

	for (io = omapi_io_states.next; io; io = io -> next) {
		if (!io -> inner)
			continue;
		omapi_object_reference (&tmp, io -> inner, MDL);
		/* Check for a read descriptor, and if there is one,
		   see if we got input on that socket. */
		if (io -> readfd &&
		    (desc = (*(io -> readfd)) (tmp)) >= 0) {
			if (FD_ISSET (desc, &r))
				((*(io -> reader)) (tmp));
		}
		
		/* Same deal for write descriptors. */
		if (io -> writefd &&
		    (desc = (*(io -> writefd)) (tmp)) >= 0)
		{
			if (FD_ISSET (desc, &w))
				((*(io -> writer)) (tmp));
		}
		omapi_object_dereference (&tmp, MDL);
	}

	/* Now check for I/O handles that are no longer valid,
	   and remove them from the list. */
	prev = NULL;
	io = NULL;
	if (omapi_io_states.next != NULL) {
		omapi_io_reference(&io, omapi_io_states.next, MDL);
	}
	while (io != NULL) {
		if ((io->inner == NULL) || 
		    ((io->reaper != NULL) && 
		     ((io->reaper)(io->inner) != ISC_R_SUCCESS))) 
		{

			omapi_io_object_t *tmp = NULL;
			/* Save a reference to the next
			   pointer, if there is one. */
			if (io->next != NULL) {
				omapi_io_reference(&tmp, io->next, MDL);
				omapi_io_dereference(&io->next, MDL);
			}
			if (prev != NULL) {
				omapi_io_dereference(&prev->next, MDL);
				if (tmp != NULL)
					omapi_io_reference(&prev->next,
							   tmp, MDL);
			} else {
				omapi_io_dereference(&omapi_io_states.next, 
						     MDL);
				if (tmp != NULL)
					omapi_io_reference
					    (&omapi_io_states.next,
					     tmp, MDL);
				else
					omapi_signal_in(
							(omapi_object_t *)
						 	&omapi_io_states,
							"ready");
			}
			if (tmp != NULL)
				omapi_io_dereference(&tmp, MDL);

		} else {

			if (prev != NULL) {
				omapi_io_dereference(&prev, MDL);
			}
			omapi_io_reference(&prev, io, MDL);

		}

		/*
		 * Equivalent to:
		 *   io = io->next
		 * But using our reference counting voodoo.
		 */
		next = NULL;
		if (io->next != NULL) {
			omapi_io_reference(&next, io->next, MDL);
		}
		omapi_io_dereference(&io, MDL);
		if (next != NULL) {
			omapi_io_reference(&io, next, MDL);
			omapi_io_dereference(&next, MDL);
		}
	}
	if (prev != NULL) {
		omapi_io_dereference(&prev, MDL);
	}

	return ISC_R_SUCCESS;
}
Exemple #24
0
// Trigger storage service in low priority process.
void storage_service_trigger(void)
{
    trigger_event(data_storage_event_handle);
}
Exemple #25
0
// ------------------------------------------------------------------------
// class to move army on adventure map
// ------------------------------------------------------------------------
void t_army_mover::do_movement()
{
	int							frame = m_army->get_frame();
	int							frame_count = m_army->get_frame_count();
	t_adv_actor_action_id		action = m_army->get_action();
	t_uint32					current_time = get_time();
	t_uint32					next_time = get_next_time() - get_delay();
	t_counted_ptr<t_army_mover> ref = this;
	t_window_ptr				adv_frame = m_window->get_frame();	// temporary reference to prevent the adventure frame
																	// from removing itself if the game is over
	bool						entered_new_square = false;

	declare_timer( timer_1, "do_movement" );
	while ( m_frames > 0 && (!m_is_visible || elapsed_time( current_time, next_time ) >= 0) )
	{
		m_offset += m_delta;
		m_cell_distance -= m_distance_delta;
		if (m_cell_distance <= m_crossing_point)
		{
			enter_new_square();
		}
		m_army->set_frame_offset( m_offset / m_divisor );
		frame++;
		if (action == k_adv_actor_action_walk && frame == frame_count)
			frame = 0;
		if (frame < frame_count)
			m_army->set_frame( frame );
		m_frames--;
		if (m_is_visible)
			next_time += get_delay();
	}
	if (m_is_visible)
		set_next_time( next_time );
	// if m_frames is zero, we've hit the center of the cell, or we've
	// finished a prewalk / walk / postwalk sequence
	if (m_frames == 0)
	{
		if ((action == k_adv_actor_action_postwalk || m_path.size() == 0)
			&& m_distance + m_cell_distance == 0)
		{
			finish_path();
			return;
		}
		if (m_cell_distance == 0) 
		{
			start_new_square();

			entered_new_square = true;

			trigger_event();
			if (m_halted) 
				return;
		}
		else
		{
			m_cell_distance /= m_divisor;
			m_crossing_point /= m_divisor;
		}
		prepare_move( frame );
	}

	if (entered_new_square)
	{
		declare_timer( timer_2, "on_starting_new_square" );
		on_starting_new_square();
	}
}
Exemple #26
0
int API
main (int argc, char *argv[], char *envp[])
{
  initalize_syslog ();
  struct state state;
  /* TODO(wad) EVENT_BASE_FLAG_PRECISE_TIMER | EVENT_BASE_FLAG_PRECISE_TIMER */
  struct event_base *base = event_base_new();
  if (!base)
    {
      fatal ("could not allocated new event base");
    }
  /* Add three priority levels:
   * 0 - time saving.  Must be done before any other events are handled.
   * 1 - network synchronization events
   * 2 - any other events (wake, platform, etc)
   */
  event_base_priority_init (base, MAX_EVENT_PRIORITIES);
  memset (&state, 0, sizeof (state));
  set_conf_defaults (&state.opts);
  parse_argv (&state.opts, argc, argv);
  check_conf (&state);
  load_conf (&state.opts);
  check_conf (&state);
  if (!state.opts.sources)
    add_source_to_conf (&state.opts, DEFAULT_HOST, DEFAULT_PORT, DEFAULT_PROXY);
  state.base = base;
  state.envp = envp;
  state.backoff = state.opts.wait_between_tries;
  /* TODO(wad) move this into setup_time_setter */
  /* grab a handle to /dev/rtc for time-setter. */
  if (state.opts.should_sync_hwclock &&
      platform->rtc_open(&state.hwclock))
    {
      pinfo ("can't open hwclock fd");
      state.opts.should_sync_hwclock = 0;
    }
  /* install the SIGCHLD handler for the setter and tlsdate */
  if (setup_sigchld_event (&state, 1))
    {
      error ("Failed to setup SIGCHLD event");
      goto out;
    }
  /* fork off the privileged helper */
  info ("spawning time setting helper . . .");
  if (setup_time_setter (&state))
    {
      error ("could not fork privileged coprocess");
      goto out;
    }
  /* release the hwclock now that the time-setter is running. */
  if (state.opts.should_sync_hwclock)
    {
      platform->rtc_close (&state.hwclock);
    }
  /* drop privileges before touching any untrusted data */
  drop_privs_to (state.opts.user, state.opts.group);
  /* register a signal handler to save time at shutdown */
  if (state.opts.should_save_disk)
    {
      struct event *event = event_new (base, SIGTERM, EV_SIGNAL|EV_PERSIST,
                                       action_sigterm, &state);
      if (!event)
        fatal ("Failed to create SIGTERM event");
      event_priority_set (event, PRI_SAVE);
      event_add (event, NULL);
    }
  if (state.opts.should_dbus && init_dbus (&state))
    {
      error ("Failed to initialize DBus");
      goto out;
    }
  /* Register the tlsdate event before any listeners could show up. */
  state.events[E_TLSDATE] = event_new (base, -1, EV_TIMEOUT,
                                       action_run_tlsdate, &state);
  if (!state.events[E_TLSDATE])
    {
      error ("Failed to create tlsdate event");
      goto out;
    }
  event_priority_set (state.events[E_TLSDATE], PRI_NET);
  /* The timeout and fd will be filled in per-call. */
  if (setup_tlsdate_status (&state))
    {
      error ("Failed to create tlsdate status event");
      goto out;
    }
  /* TODO(wad) Could use a timeout on this to catch setter death? */
  /* EV_READ is for truncation/EPIPE notification */
  state.events[E_SAVE] = event_new (base, state.setter_save_fd,
                                    EV_READ|EV_WRITE, action_sync_and_save,
                                    &state);
  if (!state.events[E_SAVE])
    {
      error ("Failed to create sync & save event");
      goto out;
    }
  event_priority_set (state.events[E_SAVE], PRI_SAVE);
  /* Start by grabbing the system time. */
  state.last_sync_type = SYNC_TYPE_RTC;
  state.last_time = time (NULL);
  /* If possible, grab disk time and check the two. */
  if (state.opts.should_load_disk)
    {
      time_t disk_time = state.last_time;
      if (!load_disk_timestamp (state.timestamp_path, &disk_time))
        {
          info ("disk timestamp available: yes");
          if (!is_sane_time (state.last_time) ||
              state.last_time < disk_time)
            {
              state.last_sync_type = SYNC_TYPE_DISK;
              state.last_time = disk_time;
            }
        }
      else
        {
          info ("disk timestamp available: no");
        }
    }
  if (!is_sane_time (state.last_time))
    {
      state.last_sync_type = SYNC_TYPE_BUILD;
      state.last_time = RECENT_COMPILE_DATE + 1;
    }
  /* Save and announce the initial time source. */
  trigger_event (&state, E_SAVE, -1);
  info ("initial time sync type: %s", sync_type_str (state.last_sync_type));
  /* Initialize platform specific loop behavior */
  if (platform_init_cros (&state))
    {
      error ("Failed to initialize platform code");
      goto out;
    }
  if (setup_event_route_up (&state))
    {
      error ("Failed to setup route up monitoring");
      goto out;
    }
  if (setup_event_timer_sync (&state))
    {
      error ("Failed to setup a timer event");
      goto out;
    }
  if (setup_event_timer_continuity (&state))
    {
      error ("Failed to setup continuity timer");
      goto out;
    }
  /* Add a forced sync event to the event list. */
  action_kickoff_time_sync (-1, EV_TIMEOUT, &state);
  info ("Entering dispatch . . .");
  event_base_dispatch (base);
  info ("tlsdated terminating gracefully");
out:
  return cleanup_main (&state);
}
			void	WindowsXbox360ControllerDevice::update( const unsigned long id )
			{
				Core::Message	parameters(5,0,0);
				HWND			foreground = GetForegroundWindow();



				if ( this->_window_handle == foreground )
				{
					parameters.add_integral_data(0,id);
					parameters.add_integral_data(2,this->_id);
					memcpy(&this->_previous_state,&this->_current_state,sizeof(XINPUT_STATE));

					if ( XInputGetState(static_cast<DWORD>(this->_id),&this->_current_state)  ==  ERROR_SUCCESS )
					{
						parameters.add_integral_data(3,static_cast<Core::MESSAGE_INTEGRAL_DATA_TYPE>(this->_current_state.Gamepad.sThumbLX));
						parameters.add_integral_data(4,static_cast<Core::MESSAGE_INTEGRAL_DATA_TYPE>(this->_current_state.Gamepad.sThumbLY));
						trigger_event(Core::XBOX360_CONTROLLER_LEFTSTICK_POSITION,parameters);

						parameters.add_integral_data(3,static_cast<Core::MESSAGE_INTEGRAL_DATA_TYPE>(this->_current_state.Gamepad.sThumbRX));
						parameters.add_integral_data(4,static_cast<Core::MESSAGE_INTEGRAL_DATA_TYPE>(this->_current_state.Gamepad.sThumbRY));
						trigger_event(Core::XBOX360_CONTROLLER_RIGHTSTICK_POSITION,parameters);

						if ( this->_previous_state.dwPacketNumber != this->_current_state.dwPacketNumber )
						{
							int	difference_left_x = this->_current_state.Gamepad.sThumbLX - this->_previous_state.Gamepad.sThumbLX;
							int	difference_left_y = this->_current_state.Gamepad.sThumbLY - this->_previous_state.Gamepad.sThumbLY;
							int	difference_right_x = this->_current_state.Gamepad.sThumbRX - this->_previous_state.Gamepad.sThumbRX;
							int	difference_right_y = this->_current_state.Gamepad.sThumbRY - this->_previous_state.Gamepad.sThumbRY;



							if ( abs(difference_left_x) > this->_deadzone  ||  abs(difference_left_y) > this->_deadzone )
							{
								parameters.add_integral_data(3,static_cast<Core::MESSAGE_INTEGRAL_DATA_TYPE>(difference_left_x));
								parameters.add_integral_data(4,static_cast<Core::MESSAGE_INTEGRAL_DATA_TYPE>(difference_left_y));
								trigger_event(Core::XBOX360_CONTROLLER_LEFTSTICK_POSITION_CHANGED,parameters);
							}

							if ( abs(difference_right_x) > this->_deadzone  ||  abs(difference_right_y) > this->_deadzone )
							{
								parameters.add_integral_data(3,static_cast<Core::MESSAGE_INTEGRAL_DATA_TYPE>(difference_right_x));
								parameters.add_integral_data(4,static_cast<Core::MESSAGE_INTEGRAL_DATA_TYPE>(difference_right_y));
								trigger_event(Core::XBOX360_CONTROLLER_RIGHTSTICK_POSITION_CHANGED,parameters);
							}


							int	up = (this->_current_state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP) - (this->_previous_state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP);
							int	down = (this->_current_state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN) - (this->_previous_state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN);
							int	left = (this->_current_state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) - (this->_previous_state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT);
							int	right = (this->_current_state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) - (this->_previous_state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT);
							int	start = (this->_current_state.Gamepad.wButtons & XINPUT_GAMEPAD_START) - (this->_previous_state.Gamepad.wButtons & XINPUT_GAMEPAD_START);
							int	back = (this->_current_state.Gamepad.wButtons & XINPUT_GAMEPAD_BACK) - (this->_previous_state.Gamepad.wButtons & XINPUT_GAMEPAD_BACK);
							int	left_thumb = (this->_current_state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB) - (this->_previous_state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB);
							int	right_thumb = (this->_current_state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) - (this->_previous_state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB);
							int	left_shoulder = (this->_current_state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) - (this->_previous_state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER);
							int	right_shoulder = (this->_current_state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER) - (this->_previous_state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER);
							int	a = (this->_current_state.Gamepad.wButtons & XINPUT_GAMEPAD_A) - (this->_previous_state.Gamepad.wButtons & XINPUT_GAMEPAD_A);
							int	b = (this->_current_state.Gamepad.wButtons & XINPUT_GAMEPAD_B) - (this->_previous_state.Gamepad.wButtons & XINPUT_GAMEPAD_B);
							int	x = (this->_current_state.Gamepad.wButtons & XINPUT_GAMEPAD_X) - (this->_previous_state.Gamepad.wButtons & XINPUT_GAMEPAD_X);
							int	y = (this->_current_state.Gamepad.wButtons & XINPUT_GAMEPAD_Y) - (this->_previous_state.Gamepad.wButtons & XINPUT_GAMEPAD_Y);
							int	left_trigger = this->_current_state.Gamepad.bLeftTrigger - this->_previous_state.Gamepad.bLeftTrigger;
							int	right_trigger = this->_current_state.Gamepad.bRightTrigger - this->_previous_state.Gamepad.bRightTrigger;



							parameters.add_integral_data(3,0);
							parameters.add_integral_data(4,0);

							if ( up < 0 )
								trigger_event(Core::XBOX360_CONTROLLER_DPAD_UP_UP,parameters);
							else if ( up > 0 )
								trigger_event(Core::XBOX360_CONTROLLER_DPAD_UP_DOWN,parameters);

							if ( down < 0 )
								trigger_event(Core::XBOX360_CONTROLLER_DPAD_DOWN_UP,parameters);
							else if ( down > 0 )
								trigger_event(Core::XBOX360_CONTROLLER_DPAD_DOWN_DOWN,parameters);

							if ( left < 0 )
								trigger_event(Core::XBOX360_CONTROLLER_DPAD_LEFT_UP,parameters);
							else if ( left > 0 )
								trigger_event(Core::XBOX360_CONTROLLER_DPAD_LEFT_DOWN,parameters);

							if ( right < 0 )
								trigger_event(Core::XBOX360_CONTROLLER_DPAD_RIGHT_UP,parameters);
							else if ( right > 0 )
								trigger_event(Core::XBOX360_CONTROLLER_DPAD_RIGHT_DOWN,parameters);

							if ( start < 0 )
								trigger_event(Core::XBOX360_CONTROLLER_START_UP,parameters);
							else if ( start > 0 )
								trigger_event(Core::XBOX360_CONTROLLER_START_DOWN,parameters);

							if ( back < 0 )
								trigger_event(Core::XBOX360_CONTROLLER_BACK_UP,parameters);
							else if ( back > 0 )
								trigger_event(Core::XBOX360_CONTROLLER_BACK_DOWN,parameters);

							if ( left_thumb < 0 )
								trigger_event(Core::XBOX360_CONTROLLER_LEFTSTICK_UP,parameters);
							else if ( left_thumb > 0 )
								trigger_event(Core::XBOX360_CONTROLLER_LEFTSTICK_DOWN,parameters);

							if ( right_thumb < 0 )
								trigger_event(Core::XBOX360_CONTROLLER_RIGHTSTICK_UP,parameters);
							else if ( right_thumb > 0 )
								trigger_event(Core::XBOX360_CONTROLLER_RIGHTSTICK_DOWN,parameters);

							if ( left_shoulder < 0 )
								trigger_event(Core::XBOX360_CONTROLLER_LEFTSHOULDER_UP,parameters);
							else if ( left_shoulder > 0 )
								trigger_event(Core::XBOX360_CONTROLLER_LEFTSHOULDER_DOWN,parameters);

							if ( right_shoulder < 0 )
								trigger_event(Core::XBOX360_CONTROLLER_RIGHTSHOULDER_UP,parameters);
							else if ( right_shoulder > 0 )
								trigger_event(Core::XBOX360_CONTROLLER_RIGHTSHOULDER_DOWN,parameters);

							if ( a < 0 )
								trigger_event(Core::XBOX360_CONTROLLER_A_UP,parameters);
							else if ( a > 0 )
								trigger_event(Core::XBOX360_CONTROLLER_A_DOWN,parameters);

							if ( b < 0 )
								trigger_event(Core::XBOX360_CONTROLLER_B_UP,parameters);
							else if ( b > 0 )
								trigger_event(Core::XBOX360_CONTROLLER_B_DOWN,parameters);

							if ( x < 0 )
								trigger_event(Core::XBOX360_CONTROLLER_X_UP,parameters);
							else if ( x > 0 )
								trigger_event(Core::XBOX360_CONTROLLER_X_DOWN,parameters);

							if ( y < 0 )
								trigger_event(Core::XBOX360_CONTROLLER_Y_UP,parameters);
							else if ( y > 0 )
								trigger_event(Core::XBOX360_CONTROLLER_Y_DOWN,parameters);


							parameters.add_integral_data(3,static_cast<Core::MESSAGE_INTEGRAL_DATA_TYPE>(left_trigger));
							if ( left_trigger < 0 )
								trigger_event(Core::XBOX360_CONTROLLER_LEFTTRIGGER_UP,parameters);
							else if ( left_trigger > 0 )
								trigger_event(Core::XBOX360_CONTROLLER_LEFTTRIGGER_DOWN,parameters);

							parameters.add_integral_data(3,static_cast<Core::MESSAGE_INTEGRAL_DATA_TYPE>(right_trigger));
							if ( right_trigger < 0 )
								trigger_event(Core::XBOX360_CONTROLLER_RIGHTTRIGGER_UP,parameters);
							else if ( right_trigger > 0 )
								trigger_event(Core::XBOX360_CONTROLLER_RIGHTTRIGGER_DOWN,parameters);
						}
					}
				}
			};
Exemple #28
0
/**
 * Pick up object.
 * @param pl Object that is picking up the object.
 * @param op Object to put tmp into.
 * @param tmp Object to pick up.
 * @param nrof Number to pick up (0 means all of them). */
static void pick_up_object(object *pl, object *op, object *tmp, int nrof)
{
	char buf[HUGE_BUF];
	object *env = tmp->env;
	int tmp_nrof = tmp->nrof ? tmp->nrof : 1;

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

	/* IF the player is flying & trying to take the item out of a container
	 * that is in his inventory, let him.  tmp->env points to the container
	 * (sack, luggage, etc), tmp->env->env then points to the player (nested
	 * containers not allowed as of now) */
	if (QUERY_FLAG(pl, FLAG_FLYING) && !QUERY_FLAG(pl, FLAG_WIZ) && is_player_inv(tmp) != pl)
	{
		new_draw_info(NDI_UNIQUE, pl, "You are levitating, you can't reach the ground!");
		return;
	}

	if (QUERY_FLAG(tmp, FLAG_WAS_WIZ) && !QUERY_FLAG(pl, FLAG_WAS_WIZ))
	{
		new_draw_info(NDI_UNIQUE, pl, "The object disappears in a puff of smoke!\nIt must have been an illusion.");

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

		if (!QUERY_FLAG(tmp, FLAG_REMOVED))
		{
			remove_ob(tmp);
			check_walk_off(tmp, NULL, MOVE_APPLY_VANISHED);
		}

		return;
	}

	if (nrof > tmp_nrof || nrof == 0)
	{
		nrof = tmp_nrof;
	}

	if (!player_can_carry(pl, tmp, nrof))
	{
		new_draw_info(NDI_UNIQUE, pl, "That item is too heavy for you to pick up.");
		return;
	}

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

	/* Trigger the PICKUP event */
	if (trigger_event(EVENT_PICKUP, pl, tmp, op, NULL, tmp_nrof, 0, 0, SCRIPT_FIX_ACTIVATOR))
	{
		return;
	}

#ifndef REAL_WIZ
	if (QUERY_FLAG(pl, FLAG_WAS_WIZ))
	{
		SET_FLAG(tmp, FLAG_WAS_WIZ);
	}
#endif

	if (QUERY_FLAG(tmp, FLAG_UNPAID))
	{
		/* This is a clone shop - clone an item for inventory */
		if (QUERY_FLAG(tmp, FLAG_NO_PICK))
		{
			tmp = object_create_clone(tmp);
			CLEAR_FLAG(tmp, FLAG_NO_PICK);
			SET_FLAG(tmp, FLAG_STARTEQUIP);
			tmp->nrof = nrof;
			tmp_nrof = nrof;
			snprintf(buf, sizeof(buf), "You pick up %s for %s from the storage.", query_name(tmp, NULL), query_cost_string(tmp, pl, F_BUY));
		}
		/* This is an unique shop item */
		else
		{
			tmp->nrof = nrof;
			snprintf(buf, sizeof(buf), "%s will cost you %s.", query_name(tmp, NULL), query_cost_string(tmp, pl, F_BUY));
			tmp->nrof = tmp_nrof;
		}
	}
	else
	{
		tmp->nrof = nrof;
		snprintf(buf, sizeof(buf), "You pick up the %s.", query_name(tmp, NULL));
		tmp->nrof = tmp_nrof;
	}

	if (nrof != tmp_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, pl, err);
			return;
		}

		/* Tell the client what happened to rest of the objects */
		if (pl->type == PLAYER)
		{
			if (was_destroyed(tmp2, tmp2_tag))
			{
				esrv_del_item(CONTR(pl), tmp2_tag, tmp2_cont);
			}
			else
			{
				esrv_send_item(pl, tmp2);
			}
		}
	}
	else
	{
		/* If the object is in a container, send a delete to the client.
		 * - we are moving all the items from the container to elsewhere,
		 * so it needs to be deleted. */
		if (!QUERY_FLAG(tmp, FLAG_REMOVED))
		{
			if (tmp->env && pl->type == PLAYER)
			{
				esrv_del_item (CONTR(pl), tmp->count, tmp->env);
			}

			/* Unlink it - no move off check */
			remove_ob(tmp);
		}
	}

	new_draw_info(NDI_UNIQUE, pl, buf);
	tmp = insert_ob_in_ob(tmp, op);

	/* All the stuff below deals with client/server code, and is only
	 * usable by players */
	if (pl->type != PLAYER)
	{
		return;
	}

	esrv_send_item(pl, tmp);
	/* These are needed to update the weight for the container we
	 * are putting the object in, and the players weight, if different. */
	esrv_update_item(UPD_WEIGHT, pl, op);

	if (op != pl)
	{
		esrv_send_item(pl, pl);
	}

	/* Update the container the object was in */
	if (env && env != pl && env != op)
	{
		esrv_update_item(UPD_WEIGHT, pl, env);
	}
}
Exemple #29
0
// Trigger the I2C1 service routine to run at low priority
void I2C1_trigger_service(void)
{
    trigger_event(I2C1_service_handle);
}
Exemple #30
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;
}