Exemplo n.º 1
0
/**
 * Basic single-frame area hazard
 */
bool PowerManager::single(int power_index, StatBlock *src_stats, Point target) {
	
	Hazard *haz = new Hazard();
	
	// common to all singles
	haz->pos.x = (float)target.x;
	haz->pos.y = (float)target.y;
	haz->lifespan = 1;
	haz->crit_chance = src_stats->crit;
	haz->accuracy = src_stats->accuracy;
	haz->src_stats = src_stats;

	// specific powers have different stats here
	if (power_index == POWER_VENGEANCE) {
		haz->pos = calcVector(src_stats->pos, src_stats->direction, src_stats->melee_range);
		haz->dmg_min = src_stats->dmg_melee_min;
		haz->dmg_max = src_stats->dmg_melee_max;
		haz->radius = 64;
		src_stats->mp--;
		
		// use vengeance stacks
		haz->accuracy += src_stats->vengeance_stacks * 25;
		haz->crit_chance += src_stats->vengeance_stacks * 25;
		src_stats->vengeance_stacks = 0;
	}
	
	hazards.push(haz);

	// Hazard memory is now the responsibility of HazardManager
	return true;
}
Exemplo n.º 2
0
/*----------------------------------------------------------------------------*/
static void enableInterrupt(const struct PinInterrupt *interrupt)
{
  const IrqNumber irq = calcVector(interrupt->channel);

  LPC_GPIO_INT->IST = 1UL << interrupt->pin.offset;
  irqClearPending(irq);
  irqEnable(irq);
}
Exemplo n.º 3
0
/**
 * Set a target depending on how a power was triggered
 */
FPoint MenuActionBar::setTarget(bool have_aim, bool aim_assist) {
	if (have_aim && MOUSE_AIM) {
		if (aim_assist)
			return screen_to_map(inpt->mouse.x,  inpt->mouse.y + AIM_ASSIST, pc->stats.pos.x, pc->stats.pos.y);
		else
			return screen_to_map(inpt->mouse.x,  inpt->mouse.y, pc->stats.pos.x, pc->stats.pos.y);
	}
	else {
		return calcVector(pc->stats.pos, pc->stats.direction, pc->stats.melee_range);
	}
}
Exemplo n.º 4
0
/*----------------------------------------------------------------------------*/
static enum Result pinInterruptInit(void *object, const void *configBase)
{
  const struct PinInterruptConfig * const config = configBase;
  assert(config);

  const struct Pin input = pinInit(config->pin);
  assert(pinValid(input));

  /* Try to allocate a new channel */
  struct PinInterrupt * const interrupt = object;
  const int channel = setInstance(interrupt);

  if (channel == -1)
    return E_BUSY;

  /* Configure the pin */
  pinInput(input);
  pinSetPull(input, config->pull);

  interrupt->callback = 0;
  interrupt->channel = channel;
  interrupt->enabled = false;
  interrupt->event = config->event;
  interrupt->pin = input.data;

  const uint8_t index = interrupt->channel >> 2;
  const uint32_t mask = 1UL << interrupt->channel;

  /* Enable peripheral */
  if (!sysClockStatus(CLK_PINT))
    sysClockEnable(CLK_PINT);

  /* Select pin and port */
  LPC_SYSCON->PINTSEL[index] =
      (LPC_SYSCON->PINTSEL[index] & ~PINTSEL_CHANNEL_MASK(channel))
      | PINTSEL_CHANNEL(channel, input.data.port, input.data.offset);
  /* Configure interrupt as edge sensitive */
  LPC_GPIO_INT->ISEL &= ~mask;
  /* Configure edge sensitivity options */
  if (config->event == PIN_RISING || config->event == PIN_TOGGLE)
    LPC_GPIO_INT->SIENR = mask;
  if (config->event == PIN_FALLING || config->event == PIN_TOGGLE)
    LPC_GPIO_INT->SIENF = mask;

#ifdef CONFIG_PM
  /* Interrupt will wake the controller from low-power modes */
  LPC_SYSCON->STARTERP0 |= STARTERP0_PINT(interrupt->channel);
#endif

  /* Configure interrupt priority, interrupt is disabled by default */
  irqSetPriority(calcVector(interrupt->channel), config->priority);

  return E_OK;
}
Exemplo n.º 5
0
void ListWeatherCloud::renderClouds(){
	//if (cycle_i > time_of_rain) renderRainfall();
    renderRainfall(); // TODO: remove this line, uncomment previous

	if ( (clouds_arr_initialized) && (!cloud_list.empty()) ){
		std::list<WeatherCloud*>::iterator it=cloud_list.begin();
		WeatherCloud *cloud;
		Sprite *spr_cloud;
		Point p;
		FPoint fp;
		Point dest_p;
		int i, j, nr=0;

		i=-RADIUS;
		j=0; // -> with j=-RADIUS: segmentation faults quite common

		while (j < RADIUS){
			// use a cloud from the list several times if needed
			if ((it == cloud_list.end())) it=cloud_list.begin();

			cloud = *it;
			if (cloud==NULL){
				it++;
				continue; // break;
			}

			spr_cloud = cloud->getSprite();

			if (spr_cloud==NULL) break;

			fp.x = cloud_state[nr][4] + i;
			fp.y = cloud_state[nr][5] + j;
			if (!isWithin(mapr->cam,RADIUS + 4,fp)){
				// move cloud to the opposite direction
				direction = calcDirection(mapr->cam.x, mapr->cam.y, fp.x, fp.y);
				if (direction < 4) direction +=4;
				else direction -=4;
				FPoint fpn = calcVector(fp, direction, RADIUS+24);
				cloud_state[nr][4] = floor(fpn.x) - i;
				cloud_state[nr][5] = floor(fpn.y) - j;
			}

			p = map_to_screen(cloud_state[nr][4] + i, cloud_state[nr][5] + j, mapr->cam.x, mapr->cam.y);
			if (cycle_i % RENDER_CHANGE_AFTER/2 == 0) {
				// TODO: should depend on wind direction and perhaps speed;
				cloud_state[nr][2] = cloud_state[nr][2] + randBetween(1,2);
				cloud_state[nr][3] = cloud_state[nr][3] + randBetween(1,2);
				direction = calcDirection(0.0,0.0, cloud_state[nr][2], cloud_state[nr][3]);
			} // overflow of cloud_state[nr][2] possible, but with little consequences

			dest_p.x = p.x + (cloud_state[nr][2] % 800) - 400;
			dest_p.y = p.y + (cloud_state[nr][3] % 600) - 300;

			spr_cloud->setOffset(cloud_state[nr][1],cloud_state[nr][1]);
			spr_cloud->setDest(dest_p);

			render_device->render(spr_cloud);

			i+=cloud_distance;
			if (i>RADIUS){
				i=-RADIUS;
				j+=cloud_distance;
			}
			it++;
			nr++;
        }

	}
}
Exemplo n.º 6
0
void Avatar::handlePower(std::vector<ActionData> &action_queue) {
	bool blocking = false;

	for (unsigned i=0; i<action_queue.size(); i++) {
		ActionData &action = action_queue[i];
		const Power &power = powers->getPower(action.power);

		if (power.type == POWTYPE_BLOCK)
			blocking = true;

		if (action.power != 0 && (stats.cooldown_ticks == 0 || action.instant_item)) {
			FPoint target = action.target;

			// check requirements
			if ((stats.cur_state == AVATAR_ATTACK || stats.cur_state == AVATAR_HIT) && !action.instant_item)
				continue;
			if (!stats.canUsePower(power, action.power))
				continue;
			if (power.requires_los && !mapr->collider.line_of_sight(stats.pos.x, stats.pos.y, target.x, target.y))
				continue;
			if (power.requires_empty_target && !mapr->collider.is_empty(target.x, target.y))
				continue;
			if (hero_cooldown[action.power] > 0)
				continue;
			if (!powers->hasValidTarget(action.power, &stats, target))
				continue;

			// automatically target the selected enemy with melee attacks
			if (power.type == POWTYPE_FIXED && power.starting_pos == STARTING_POS_MELEE && enemy_pos.x != -1 && enemy_pos.y != -1) {
				target = enemy_pos;
			}

			// is this a power that requires changing direction?
			if (power.face) {
				stats.direction = calcDirection(stats.pos, target);
			}

			// draw a target on the ground if we're attacking
			if (!power.buff && !power.buff_teleport &&
			    power.type != POWTYPE_TRANSFORM && power.type != POWTYPE_BLOCK &&
			    !(power.starting_pos == STARTING_POS_SOURCE && power.speed == 0))
			{
				if (power.starting_pos == STARTING_POS_TARGET && power.target_range > 0) {
					target_pos = clampDistance(power.target_range, stats.pos, target);
				}
				else if (power.starting_pos == STARTING_POS_MELEE) {
					target_pos = calcVector(stats.pos, stats.direction, stats.melee_range);
				}
				else {
					target_pos = target;
				}

				if (target_anim) {
					target_visible = true;
					target_anim->reset();
				}
				lock_cursor = true;
			}
			else {
				curs->setCursor(CURSOR_NORMAL);
			}

			if (power.new_state != POWSTATE_INSTANT) {
				current_power = action.power;
				act_target = target;
				attack_anim = power.attack_anim;
			}

			if (power.state_duration > 0)
				stats.state_ticks = power.state_duration;

			if (power.charge_speed != 0.0f)
				stats.charge_speed = power.charge_speed;

			switch (power.new_state) {
				case POWSTATE_ATTACK:	// handle attack powers
					stats.cur_state = AVATAR_ATTACK;
					break;

				case POWSTATE_INSTANT:	// handle instant powers
					powers->activate(action.power, &stats, target);
					hero_cooldown[action.power] = power.cooldown;
					break;

				default:
					if (power.type == POWTYPE_BLOCK) {
						stats.cur_state = AVATAR_BLOCK;
						powers->activate(action.power, &stats, target);
						hero_cooldown[action.power] = power.cooldown;
						stats.refresh_stats = true;
					}
					break;
			}
		}
	}

	stats.blocking = blocking;
}
Exemplo n.º 7
0
/**
 * Apply basic power info to a new hazard.
 *
 * This can be called several times to combine powers.
 * Typically done when a base power can be modified by equipment
 * (e.g. ammo type affects the traits of powers that shoot)
 *
 * @param power_index The activated power ID
 * @param src_stats The StatBlock of the power activator
 * @param target Aim position in map coordinates
 * @param haz A newly-initialized hazard
 */
void PowerManager::initHazard(int power_index, StatBlock *src_stats, Point target, Hazard *haz) {

	//the hazard holds the statblock of its source
	haz->src_stats = src_stats;

	// Hazard attributes based on power source
	haz->crit_chance = src_stats->crit;
	haz->accuracy = src_stats->accuracy;
	
	// Hazard damage depends on equipped weapons and the power's optional damage_multiplier
	if (powers[power_index].base_damage == BASE_DAMAGE_MELEE) {
		haz->dmg_min = src_stats->dmg_melee_min;
		haz->dmg_max = src_stats->dmg_melee_max;
	}
	else if (powers[power_index].base_damage == BASE_DAMAGE_RANGED) {
		haz->dmg_min = src_stats->dmg_ranged_min;
		haz->dmg_max = src_stats->dmg_ranged_max;
	}
	else if (powers[power_index].base_damage == BASE_DAMAGE_MENT) {
		haz->dmg_min = src_stats->dmg_ment_min;
		haz->dmg_max = src_stats->dmg_ment_max;
	}
	//apply the multiplier
	haz->dmg_min = ceil(haz->dmg_min * powers[power_index].damage_multiplier / 100.0);
	haz->dmg_max = ceil(haz->dmg_max * powers[power_index].damage_multiplier / 100.0);
	
	// Only apply stats from powers that are not defaults
	// If we do this, we can init with multiple power layers
	// (e.g. base spell plus weapon type)
	
	if (powers[power_index].gfx_index != -1) {
		haz->sprites = gfx[powers[power_index].gfx_index];
	}
	if (powers[power_index].rendered) {
		haz->rendered = powers[power_index].rendered;
	}
	if (powers[power_index].lifespan != 0) {
		haz->lifespan = powers[power_index].lifespan;
	}
	if (powers[power_index].frame_loop != 1) {
		haz->frame_loop = powers[power_index].frame_loop;
	}
	if (powers[power_index].frame_duration != 1) {
		haz->frame_duration = powers[power_index].frame_duration;
	}
	if (powers[power_index].frame_size.x != 0) {
		haz->frame_size.x = powers[power_index].frame_size.x;
	}
	if (powers[power_index].frame_size.y != 0) {
		haz->frame_size.y = powers[power_index].frame_size.y;
	}
	if (powers[power_index].frame_offset.x != 0) {
		haz->frame_offset.x = powers[power_index].frame_offset.x;
	}
	if (powers[power_index].frame_offset.y != 0) {
		haz->frame_offset.y = powers[power_index].frame_offset.y;
	}
	if (powers[power_index].directional) {
		haz->direction = calcDirection(src_stats->pos.x, src_stats->pos.y, target.x, target.y);
	}
	else if (powers[power_index].visual_random != 0) {
		haz->visual_option = rand() % powers[power_index].visual_random;
	}
	else if (powers[power_index].visual_option != 0) {
		haz->visual_option = powers[power_index].visual_option;
	}
	haz->floor = powers[power_index].floor;
	if (powers[power_index].speed > 0) {
		haz->base_speed = powers[power_index].speed;
	}
	if (powers[power_index].complete_animation) {
		haz->complete_animation = true;
	}
	
	// combat traits
	if (powers[power_index].no_attack) {
		haz->active = false;
	}
	if (powers[power_index].multitarget) {
		haz->multitarget = true;
	}
	if (powers[power_index].active_frame != -1) {
		haz->active_frame = powers[power_index].active_frame;
	}
	if (powers[power_index].radius != 0) {
		haz->radius = powers[power_index].radius;
	}
	if (powers[power_index].trait_armor_penetration) {
		haz->trait_armor_penetration = true;
	}
	haz->trait_crits_impaired = powers[power_index].trait_crits_impaired;
	if (powers[power_index].trait_elemental) {
		haz->trait_elemental = powers[power_index].trait_elemental;
	}
	
	// status effect durations
	// durations stack when combining powers (e.g. base power and weapon/ammo type)
	haz->bleed_duration += powers[power_index].bleed_duration;
	haz->stun_duration += powers[power_index].stun_duration;
	haz->slow_duration += powers[power_index].slow_duration;
	haz->immobilize_duration += powers[power_index].immobilize_duration;
	// steal effects
	haz->hp_steal += powers[power_index].hp_steal;
	haz->mp_steal += powers[power_index].mp_steal;
	
	// hazard starting position
	if (powers[power_index].starting_pos == STARTING_POS_SOURCE) {
		haz->pos.x = (float)src_stats->pos.x;
		haz->pos.y = (float)src_stats->pos.y;
	}
	else if (powers[power_index].starting_pos == STARTING_POS_TARGET) {
		haz->pos.x = (float)target.x;
		haz->pos.y = (float)target.y;	
	}
	else if (powers[power_index].starting_pos == STARTING_POS_MELEE) {
		haz->pos = calcVector(src_stats->pos, src_stats->direction, src_stats->melee_range);
	}
	
	// pre/post power effects
	if (powers[power_index].post_power != -1) {
		haz->post_power = powers[power_index].post_power;
	}
	if (powers[power_index].wall_power != -1) {
		haz->wall_power = powers[power_index].wall_power;
	}
	
	// if equipment has special powers, apply it here (if it hasn't already been applied)
	if (!haz->equipment_modified && powers[power_index].allow_power_mod) {
		if (powers[power_index].base_damage == BASE_DAMAGE_MELEE && src_stats->melee_weapon_power != -1) {
			haz->equipment_modified = true;
			initHazard(src_stats->melee_weapon_power, src_stats, target, haz);
		}
		else if (powers[power_index].base_damage == BASE_DAMAGE_MENT && src_stats->mental_weapon_power != -1) {
			haz->equipment_modified = true;
			initHazard(src_stats->mental_weapon_power, src_stats, target, haz);
		}
		else if (powers[power_index].base_damage == BASE_DAMAGE_RANGED && src_stats->ranged_weapon_power != -1) {
			haz->equipment_modified = true;
			initHazard(src_stats->ranged_weapon_power, src_stats, target, haz);
		}		
	}
}
Exemplo n.º 8
0
/*----------------------------------------------------------------------------*/
static void disableInterrupt(const struct PinInterrupt *interrupt)
{
  irqDisable(calcVector(interrupt->channel));
}