示例#1
0
// Returns true if thread succeceed in grapping the lock, otherwise false.
bool Mutex::try_lock() {
  Thread* thread    = Thread::current();
  debug_only(check_prelock_state(thread));

  // Special case, where all Java threads are stopped. The count is not -1, but the owner
  // is not yet set. In that case the VM thread can safely grap the lock.
  bool is_vm_thread = thread->is_VM_thread();
  bool at_safepoint = SafepointSynchronize::is_at_safepoint();
  if (is_vm_thread && at_safepoint && _owner == INVALID_THREAD) {
    set_owner(thread); // Do not need to be atomic, since we are at a safepoint
    _supress_signal = true;
    return true;
  }

  // The try_lock_implementation is platform-specific
  if (try_lock_implementation()) {
    // We got the lock        
    assert(owner() == Mutex::INVALID_THREAD, "Mutex lock count and owner are inconsistent");
    set_owner(thread);
    trace("try_locks");
    return true;
  } else {
    return false;
  }
}
示例#2
0
void init_arg(mixed *args) {
  if (sizeof(args)) {
    set_owner(args[0]);
    set_color(args[1]);
    set_shortandlong(args[1]);
  }
}
示例#3
0
void Mutex::lock(Thread *thread) { 
  debug_only(check_prelock_state(thread));

  // lock_implementation is a os-specific method
  if (lock_implementation()) {
    // Success, we now own the lock
  } else {    
    bool is_vm_thread = thread->is_VM_thread();
    bool at_safepoint = SafepointSynchronize::is_at_safepoint();
    if (is_vm_thread && at_safepoint && _owner == INVALID_THREAD) {        
      // a java thread has locked the lock but has not entered the
      // critical region -- let's just pretend we've locked the lock
      // and go on.  we note this with _supress_signal so we can also
      // pretend to unlock when the time comes.
      _supress_signal = true;
    } else {
      check_block_state(thread);
      if (!thread->is_Java_thread()) {
	wait_for_lock_implementation();
      } else {	
	debug_only(assert(rank() > Mutex::special, 
	  "Potential deadlock with special or lesser rank mutex"));
	wait_for_lock_blocking_implementation((JavaThread*)thread);
      }
    }
  }

  assert(owner() == Mutex::INVALID_THREAD, "Mutex lock count and owner are inconsistent");
  set_owner(thread);
  trace("locks");  
}
void
GroupLevelObj::set_overrides(const FileReader& reader)
{
  if (reader.read_int("repeat", m_repeat))
  {
    set_repeat(m_repeat);
    m_overrides |= HAS_REPEAT;
  }

  if (reader.read_int("owner-id", m_owner_id))
  {
    set_owner(m_owner_id);
    m_overrides |= HAS_OWNER;
  }

  if (reader.read_int("release-rate", m_release_rate))
  {
    set_release_rate(m_release_rate);
    m_overrides |= HAS_RELEASE_RATE;
  }

  if (reader.read_string("direction",  m_direction))
  {
    set_direction(m_direction);
    m_overrides |= HAS_DIRECTION;
  }
}
示例#5
0
文件: town.cpp 项目: dvbuntu/ogre
// Check if town has been captured and set new owner
// Only report if there's a change of ownership
// Maybe change to unit checks when it stops moving
OgrePlayer *OgreTown::check_conquest(std::list<OgreUnit*> units){
    sf::Vector2f town_position = get_position();

    OgrePlayer *possible_owner = nullptr;
    OgrePlayer *unit_owner;
    bool contested = false;

    // step for each level of speed
    for(auto unit : units){
        unit_owner = unit->get_owner();
        if (unit->distance<>(town_position) < TOWN_SIZE)
        {
            // Set new possible owner
            if (possible_owner == nullptr)
                possible_owner = unit_owner;
            // Multiple units, don't change owner
            // just comparing pointers, not actual ids...
            else if (possible_owner == unit_owner)
                contested = true;
                break;
        }
    }
    // set new owner and damage town
    if (!contested && possible_owner != nullptr && possible_owner != get_owner())
    {
        set_owner(possible_owner);
        pillage();
        set_info(hp);
        return possible_owner;
    }
    else
        return nullptr;
}
示例#6
0
// -----------------------------------------------------------
// object owned by a player
// -----------------------------------------------------------
bool t_owned_adv_object::read( std::streambuf&					 stream, 
							   t_qualified_adv_object_type const& type,
							   int								 version )
{
	set_owner( get<t_int8>( stream ) );
	return true;
}
示例#7
0
	WinAbsSD::WinAbsSD(PSID owner, PSID group, PACL dacl, bool protect):
		m_owner(nullptr),
		m_group(nullptr),
		m_dacl(nullptr),
		m_sacl(nullptr)
	{
		m_sd = alloc(SECURITY_DESCRIPTOR_MIN_LENGTH);
		CheckApi(::InitializeSecurityDescriptor(m_sd, SECURITY_DESCRIPTOR_REVISION));

		try {
			m_owner = Sid::clone(owner);
			set_owner(m_sd, m_owner);
		} catch (exception::Abstract & e) {
			LogDebug(L"exception cought: %s, %s", e.what(), e.where());
		}

		try {
			m_group = Sid::clone(group);
			set_group(m_sd, m_group);
		} catch (exception::Abstract & e) {
			LogDebug(L"exception cought: %s, %s", e.what(), e.where());
		}

		try {
			WinDacl(dacl).detach(m_dacl);
			set_dacl(m_sd, m_dacl);
		} catch (exception::Abstract & e) {
			LogDebug(L"exception cought: %s, %s", e.what(), e.where());
		}

		CheckApi(::IsValidSecurityDescriptor(m_sd));
		set_protect(protect);
	}
示例#8
0
/*
 * Dedicate or undedicate a port to the companion controller.
 * Syntax is "[-]portnum", where a leading '-' sign means
 * return control of the port to the EHCI controller.
 */
static ssize_t store_companion(struct device *dev,
                               struct device_attribute *attr,
                               const char *buf, size_t count)
{
    struct ehci_hcd		*ehci;
    int			portnum, new_owner;

    ehci = hcd_to_ehci(dev_get_drvdata(dev));
    new_owner = PORT_OWNER;		/* Owned by companion */
    if (sscanf(buf, "%d", &portnum) != 1)
        return -EINVAL;
    if (portnum < 0) {
        portnum = - portnum;
        new_owner = 0;		/* Owned by EHCI */
    }
    if (portnum <= 0 || portnum > HCS_N_PORTS(ehci->hcs_params))
        return -ENOENT;
    portnum--;
    if (new_owner)
        set_bit(portnum, &ehci->companion_ports);
    else
        clear_bit(portnum, &ehci->companion_ports);
    set_owner(ehci, portnum, new_owner);
    return count;
}
/**
 * unionfs implementation of the create call
 * libfuse will call this to create regular files
 */
static int unionfs_create(const char *path, mode_t mode, struct fuse_file_info *fi) {
	DBG("%s\n", path);

	int i = find_rw_branch_cutlast(path);
	if (i == -1) RETURN(-errno);

	char p[PATHLEN_MAX];
	if (BUILD_PATH(p, uopt.branches[i].path, path)) RETURN(-ENAMETOOLONG);

	// NOTE: We should do:
	//       Create the file with mode=0 first, otherwise we might create
	//       a file as root + x-bit + suid bit set, which might be used for
	//       security racing!
	int res = open(p, fi->flags, 0);
	if (res == -1) RETURN(-errno);

	set_owner(p); // no error check, since creating the file succeeded

	// NOW, that the file has the proper owner we may set the requested mode
	fchmod(res, mode);

	fi->fh = res;
	remove_hidden(path, i);

	DBG("fd = %" PRIx64 "\n", fi->fh);
	RETURN(0);
}
示例#10
0
文件: spell_util.c 项目: atrinik/dwc
/**
 * Fires an archetype.
 * @param op Person firing the object.
 * @param caster Object casting the spell.
 * @param x X position where to fire the spell.
 * @param y Y position where to fire the spell.
 * @param dir Direction to fire in.
 * @param at The archetype to fire.
 * @param type Spell ID.
 * @return 0 on failure, 1 on success. */
int fire_arch_from_position(object *op, object *caster, sint16 x, sint16 y, int dir, archetype *at, int type, object *target)
{
	object *tmp, *env;

	if (at == NULL)
	{
		return 0;
	}

	for (env = op; env->env != NULL; env = env->env)
	{
	}

	if (env->map == NULL)
	{
		return 0;
	}

	tmp = arch_to_object(at);

	if (tmp == NULL)
	{
		return 0;
	}

	tmp->stats.sp = type;
	tmp->stats.dam = (sint16) SP_level_dam_adjust(caster, type, tmp->stats.dam);
	tmp->stats.hp = spells[type].bdur + SP_level_strength_adjust(caster, type);
	tmp->x = x, tmp->y = y;
	tmp->direction = dir;
	tmp->stats.grace = tmp->last_sp;
	tmp->stats.maxgrace = 60 + (RANDOM() % 12);
	tmp->enemy = target;

	if (get_owner(op) != NULL)
	{
		copy_owner(tmp, op);
	}
	else
	{
		set_owner(tmp, op);
	}

	tmp->level = SK_level(caster);

	if (QUERY_FLAG(tmp, FLAG_IS_TURNABLE))
	{
		SET_ANIMATION(tmp, (NUM_ANIMATIONS(tmp) / NUM_FACINGS(tmp)) * dir);
	}

	if ((tmp = insert_ob_in_map(tmp, op->map, op, 0)) == NULL)
	{
		return 1;
	}

	move_fired_arch(tmp);
	return 1;
}
示例#11
0
文件: node.cpp 项目: GovanifY/godot
void Node::_propagate_replace_owner(Node *p_owner,Node* p_by_owner) {	
	if (get_owner()==p_owner)
		set_owner(p_by_owner);
	
	data.blocked++;
	for (int i=0;i<data.children.size();i++) 
		data.children[i]->_propagate_replace_owner(p_owner,p_by_owner);
	data.blocked--;		
}
示例#12
0
void dsp_preset::contents_from_stream(stream_reader * p_stream,abort_callback & p_abort) {
	t_uint32 size;
	GUID guid;
	p_stream->read_lendian_t(guid,p_abort);
	set_owner(guid);
	p_stream->read_lendian_t(size,p_abort);
	if (size > 1024*1024*32) throw exception_io_data();
	set_data_from_stream(p_stream,size,p_abort);
}
示例#13
0
thing_data* buy( thing_data* t1, char_data* ch, thing_data* )
{
  obj_data* obj = (obj_data*) t1;
 
  obj = (obj_data*) obj->From( obj->selected );   
  set_owner( obj, ch, NULL );
  obj->To( ch );

  return obj;
}
示例#14
0
void Mutex::lock_without_safepoint_check() {
  // lock_implementation is platform specific
  if (lock_implementation()) {
    // Success, we now own the lock
  } else {    
    wait_for_lock_implementation();
  }

  assert(_owner == INVALID_THREAD, "Mutex lock count and owner are inconsistent");
  set_owner(Thread::current());
}
示例#15
0
void set_owner( obj_data* obj, pfile_data* buyer )
{
  obj_data* content;

  if( obj->pIndexData->item_type != ITEM_MONEY )
    obj->owner = buyer;

  for( int i = 0; i < obj->contents; i++ )
    if( ( content = object( obj->contents[i] ) ) != NULL )
      set_owner( content, buyer );
}
示例#16
0
void set_owner( obj_data* obj, char_data* buyer, char_data* seller )
{
  obj_data* content;

  if( obj->Belongs( seller ) && obj->pIndexData->item_type != ITEM_MONEY )
    obj->owner = ( ( buyer != NULL && buyer->pcdata != NULL )
      ? buyer->pcdata->pfile : NULL );

  for( int i = 0; i < obj->contents; i++ )
    if( ( content = object( obj->contents[i] ) ) != NULL ) 
      set_owner( content, buyer, seller );
}
示例#17
0
void set_owner( pfile_data* pfile, thing_array& array )
{
  obj_data* obj;

  for( int i = 0; i < array; i++ ) {
    if( ( obj = object( array[i] ) ) != NULL ) {
      if( obj->owner == NULL
        && obj->pIndexData->item_type != ITEM_MONEY )
        obj->owner = pfile; 
      set_owner( pfile, obj->contents );
      }
    }
}
示例#18
0
void t_sanctuary::activate_trigger( t_army* army, t_adv_map_point const& point, 
									t_direction direction, 
									t_adventure_frame* frame )
{
	t_dialog_sanctuary*				dialog;
	t_player*						player = army->get_owner();
	std::string						text;
	t_screen_point					zero(0,0);

	resurrect_heroes( *army, k_text_sanctuary_resurrects_heroes, frame );
	dialog = new t_dialog_sanctuary( frame );

	if (!empty())
	{
		dialog->set_text( get_text( "denied" ) );
		dialog->enable_entry( false );
	}
	else if (m_paid[army->get_owner_number()])
	{
		dialog->set_text( get_text( "paid" ) );
		dialog->enable_entry( true );
	}
	else
	{
		dialog->set_text( get_text( "initial" ));
		dialog->enable_entry( player->get_funds()[k_gold] >= k_rental_fee);
	}
	dialog->set_title( get_name() );

	t_sound_cache music = get_music_playing();
	stop_music();
	get_dialog_sound( k_dialog_sound_sanctuary )->play( get_sound_volume() );
	switch (dialog->run_modal())
	{
		case k_choice_cancel:
			return;

		case k_choice_enter:
			if (!m_paid[army->get_owner_number()])
			{
				player->spend( k_gold, k_rental_fee );
				m_paid[army->get_owner_number()] = true;
			}
			set_owner( army->get_owner_number() );
			swap( army->get_creatures() );
			frame->destroy_army( army );
			break;
	}
	play_music( music );
}
示例#19
0
// ------------------------------------------------------------------------
// sanctuary for armies - heal, resurrect, remain safe from harm
// ------------------------------------------------------------------------
void t_sanctuary::dump_visitors()
{
	t_adv_map_point point;

	if (!find_adjacent_space( point, *this ))
		return;
	
	t_army_ptr army;

	army = new t_army( this );
	army->set_owner( get_owner_number() );
	army->place( *m_map, point );
	set_owner( -1 );
	get_adventure_frame()->select_army( army );
	get_adventure_frame()->update();
	army->trigger_events();
}
static int unionfs_symlink(const char *from, const char *to) {
	DBG("from %s to %s\n", from, to);

	int i = find_rw_branch_cutlast(to);
	if (i == -1) RETURN(-errno);

	char t[PATHLEN_MAX];
	if (BUILD_PATH(t, uopt.branches[i].path, to)) RETURN(-ENAMETOOLONG);

	int res = symlink(from, t);
	if (res == -1) RETURN(-errno);

	set_owner(t); // no error check, since creating the file succeeded

	remove_hidden(to, i); // remove hide file (if any)
	RETURN(0);
}
示例#21
0
文件: spell_util.c 项目: atrinik/dwc
/**
 * Drops an object based on what is in the cone's "other_arch".
 * @param op The object. */
void cone_drop(object *op)
{
	object *new_ob = arch_to_object(op->other_arch);

	new_ob->x = op->x;
	new_ob->y = op->y;
	new_ob->stats.food = op->stats.hp;
	new_ob->level = op->level;
	set_owner(new_ob, op->owner);

	if (op->chosen_skill)
	{
		new_ob->chosen_skill = op->chosen_skill;
		new_ob->exp_obj = op->chosen_skill->exp_obj;
	}

	insert_ob_in_map(new_ob, op->map, op, 0);
}
/**
 * unionfs mkdir() implementation
 *
 * NOTE: Never delete whiteouts directories here, since this will just
 *       make already hidden sub-branches visible again.
 */
static int unionfs_mkdir(const char *path, mode_t mode) {
	DBG("%s\n", path);

	int i = find_rw_branch_cutlast(path);
	if (i == -1) RETURN(-errno);

	char p[PATHLEN_MAX];
	if (BUILD_PATH(p, uopt.branches[i].path, path)) RETURN(-ENAMETOOLONG);

	int res = mkdir(p, 0);
	if (res == -1) RETURN(-errno);

	set_owner(p); // no error check, since creating the file succeeded
        // NOW, that the file has the proper owner we may set the requested mode
        chmod(p, mode);

	RETURN(0);
}
示例#23
0
void t_sea_sanctuary::dump_visitors()
{
	t_adv_map_point point;

	t_army_ptr boat;

	boat = new t_army( this );
	boat->set_boat_type( boat->get_creatures().get_leader().get_alignment() );
	boat->set_owner( get_owner_number() );

	if (!find_adjacent_space( point, *boat ))
		return;
	
	boat->place( *m_map, point );
	set_owner( -1 );
	get_adventure_frame()->select_army( boat );
	get_adventure_frame()->update();
	boat->trigger_events();
}
示例#24
0
void StackLock::lock(Thread* thread, JavaOop *obj) {
  AllocationDisabler no_allocation;
  // May not necessarily be the current thread
  GUARANTEE(owner() == NULL || owner() == obj->obj(), "Sanity Check");
  GUARANTEE(thread->is_on_stack((address)this), "Sanity check");

  JavaNear::Raw real_near = obj->klass();
  GUARANTEE(!real_near().is_locked(), "Sanity check");

  // Must not use JavaNear for stack nears.
  JavaNear::Raw stack_near = java_near(&real_near);
  stack_near().set_lock(JavaNear::locked_value);

  // Object is unlocked, so we're free to lock it.
  set_owner(obj);
  set_thread(thread);
  set_real_java_near(&real_near);
  _waiters = NULL;
  obj->set_klass(&stack_near);
  GUARANTEE(Synchronizer::is_locked_by(obj, thread), "Sanity check");
}
示例#25
0
文件: spell_util.c 项目: atrinik/dwc
/**
 * The following routine creates a swarm of objects. It actually sets up
 * a specific swarm object, which then fires off all the parts of the
 * swarm.
 * @param op Who is casting.
 * @param caster What object is casting.
 * @param dir Cast direction.
 * @param swarm_type Archetype of the swarm.
 * @param spell_type ID of the spell.
 * @param n The number to be fired.
 * @param magic Magic. */
void fire_swarm(object *op, object *caster, int dir, archetype *swarm_type, int spell_type, int n, int magic)
{
	object *tmp = get_archetype("swarm_spell");

	tmp->x = op->x;
	tmp->y = op->y;
	/* Needed so that if swarm elements kill, caster gets xp. */
	set_owner(tmp, op);
	/* Needed later, to get level dep. right.*/
	tmp->level = SK_level(caster);
	/* Needed later, see move_swarm_spell */
	tmp->stats.sp = spell_type;

	tmp->magic = magic;
	/* n in swarm */
	tmp->stats.hp = n;
	/* The archetype of the things to be fired */
	tmp->other_arch = swarm_type;
	tmp->direction = dir;

	insert_ob_in_map(tmp, op->map, op, 0);
}
static int unionfs_mknod(const char *path, mode_t mode, dev_t rdev) {
	DBG("%s\n", path);

	int i = find_rw_branch_cutlast(path);
	if (i == -1) RETURN(-errno);

	char p[PATHLEN_MAX];
	if (BUILD_PATH(p, uopt.branches[i].path, path)) RETURN(-ENAMETOOLONG);

	int file_type = mode & S_IFMT;
	int file_perm = mode & (S_PROT_MASK);

	int res = -1;
	if ((file_type) == S_IFREG) {
		// under FreeBSD, only the super-user can create ordinary files using mknod
		// Actually this workaround should not be required any more
		// since we now have the unionfs_create() method
		// So can we remove it?

		USYSLOG (LOG_INFO, "deprecated mknod workaround, tell the unionfs-fuse authors if you see this!\n");

		res = creat(p, 0);
		if (res > 0 && close(res) == -1) USYSLOG(LOG_WARNING, "Warning, cannot close file\n");
	} else {
		res = mknod(p, file_type, rdev);
	}

	if (res == -1) RETURN(-errno);

	set_owner(p); // no error check, since creating the file succeeded
	// NOW, that the file has the proper owner we may set the requested mode
	chmod(p, file_perm);

	remove_hidden(path, i);

	RETURN(0);
}
示例#27
0
	WinAbsSD::WinAbsSD(const ustring& name, const ustring& group, bool prot):
		m_owner(nullptr),
		m_group(nullptr),
		m_dacl(nullptr),
		m_sacl(nullptr)
	{
		m_sd = alloc(SECURITY_DESCRIPTOR_MIN_LENGTH);
		CheckApi(::InitializeSecurityDescriptor(m_sd, SECURITY_DESCRIPTOR_REVISION));
		m_dacl = WinDacl::create(64);

		if (!name.empty()) {
			try {
				Sid usr(name.c_str());
				DWORD ownerSize = SECURITY_MAX_SID_SIZE;
				m_owner = (PSID)::LocalAlloc(LPTR, ownerSize);
				usr.copy_to(m_owner, ownerSize);
			} catch (...) {
			}
		}

		if (!group.empty()) {
			try {
				DWORD groupSize = SECURITY_MAX_SID_SIZE;
				m_group = (PSID)::LocalAlloc(LPTR, groupSize);
				Sid grp(group.c_str());
				grp.copy_to(m_group, groupSize);
			} catch (...) {
			}
		}

		set_owner(m_sd, m_owner);
		set_group(m_sd, m_group);
		set_dacl(m_sd, m_dacl);
		CheckApi(::IsValidSecurityDescriptor(m_sd));
		set_protect(prot);
	}
示例#28
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);
	}
}
示例#29
0
文件: spell_util.c 项目: atrinik/dwc
/**
 * Casts a cone spell.
 * @param op Person firing the object.
 * @param caster Object casting the spell.
 * @param dir Direction to fire in.
 * @param strength Strength of the spell.
 * @param spell_type ID of the spell.
 * @param spell_arch Spell's arch.
 * @retval 0 Couldn't cast.
 * @retval 1 Successful cast. */
int cast_cone(object *op, object *caster, int dir, int strength, int spell_type, archetype *spell_arch)
{
	object *tmp;
	int i, success = 0, range_min = -1, range_max = 1;
	uint32 count_ref;

	if (!dir)
	{
		range_min = -3, range_max = 4, strength /= 2;
	}

	/* Our initial spell object */
	tmp = arch_to_object(spell_arch);

	if (!tmp)
	{
		LOG(llevBug, "BUG: cast_cone(): arch_to_object() failed!? (%s)\n", spell_arch->name);
		return 0;
	}

	count_ref = tmp->count;

	for (i = range_min; i <= range_max; i++)
	{
		int x = op->x + freearr_x[absdir(dir + i)], y = op->y + freearr_y[absdir(dir + i)];

		if (wall(op->map, x, y))
		{
			continue;
		}

		success = 1;

		if (!tmp)
		{
			tmp = arch_to_object(spell_arch);
		}

		set_owner(tmp, op);
		copy_owner(tmp, op);
		/* *very* important - miss this and the spells go really wild! */
		tmp->weight_limit = count_ref;

		tmp->level = SK_level(caster);
		tmp->x = x, tmp->y = y;

		if (dir)
		{
			tmp->stats.sp = dir;
		}
		else
		{
			tmp->stats.sp = i;
		}

		tmp->stats.hp = strength;
		tmp->stats.dam = (sint16) SP_level_dam_adjust(caster, spell_type, tmp->stats.dam);
		tmp->stats.maxhp = tmp->count;

		if (!QUERY_FLAG(tmp, FLAG_FLYING))
		{
			LOG(llevDebug, "DEBUG: cast_cone(): arch %s doesn't have flying 1\n", spell_arch->name);
		}

		if ((!QUERY_FLAG(tmp, FLAG_WALK_ON) || !QUERY_FLAG(tmp, FLAG_FLY_ON)) && tmp->stats.dam)
		{
			LOG(llevDebug, "DEBUG: cast_cone(): arch %s doesn't have walk_on 1 and fly_on 1\n", spell_arch->name);
		}

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

		if (tmp->other_arch)
		{
			cone_drop(tmp);
		}

		tmp = NULL;
	}

	/* Can happen when we can't drop anything */
	if (tmp)
	{
		/* Was not inserted */
		if (!QUERY_FLAG(tmp, FLAG_REMOVED))
		{
			remove_ob(tmp);
		}
	}

	return success;
}
示例#30
0
文件: spell_util.c 项目: atrinik/dwc
/**
 * Cast a bolt-like spell.
 * @param op Who is casting the spell.
 * @param caster What object is casting the spell (rod, ...).
 * @param dir Firing direction.
 * @param type Spell ID.
 * @retval 0 No bolt could be fired.
 * @retval 1 Bolt was fired (but may have been destroyed already). */
int fire_bolt(object *op, object *caster, int dir, int type)
{
	object *tmp;
	int w;

	if (!spellarch[type])
	{
		return 0;
	}

	tmp = arch_to_object(spellarch[type]);

	if (!tmp)
	{
		return 0;
	}

	if (!dir)
	{
		new_draw_info(NDI_UNIQUE, op, "You can't fire that at yourself!");
		return 0;
	}

	tmp->stats.dam = (sint16) SP_level_dam_adjust(caster, type, tmp->stats.dam);
	tmp->stats.hp = spells[type].bdur + SP_level_strength_adjust(caster, type);

	tmp->direction = dir;
	tmp->x = op->x + DIRX(tmp);
	tmp->y = op->y + DIRY(tmp);

	if (QUERY_FLAG(tmp, FLAG_IS_TURNABLE))
	{
		SET_ANIMATION(tmp, (NUM_ANIMATIONS(tmp) / NUM_FACINGS(tmp)) * tmp->direction);
	}

	set_owner(tmp, op);
	tmp->level = SK_level(caster);
	w = wall(op->map, tmp->x, tmp->y);

	if (w && !QUERY_FLAG(tmp, FLAG_REFLECTING))
	{
		return 0;
	}

	if (w || reflwall(op->map, tmp->x, tmp->y, tmp))
	{
		tmp->direction = absdir(tmp->direction + 4);
		tmp->x = op->x + DIRX(tmp);
		tmp->y = op->y + DIRY(tmp);
	}

	if (wall(op->map, tmp->x, tmp->y))
	{
		new_draw_info(NDI_UNIQUE, op, "There is something in the way.");
		return 0;
	}

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

	if (tmp)
	{
		move_bolt(tmp);
	}

	return 1;
}