Example #1
0
bool Game_Battler::IsSkillUsable(int skill_id) {
	if (CalculateSkillCost(skill_id) > GetSp()) {
		return false;
	}
	// ToDo: Check for Movable(?) and Silence

	// ToDo: Escape and Teleport Spells need event SetTeleportPlace and
	// SetEscapePlace first. Not sure if any game uses this...
	//if (Data::skills[skill_id - 1].type == RPG::Skill::Type_teleport) {
	//	return is_there_a_teleport_set;
	//} else if (Data::skills[skill_id - 1].type == RPG::Skill::Type_escape) {
	//	return is_there_an_escape_set;
	//} else
	if (Data::skills[skill_id - 1].type == RPG::Skill::Type_normal) {
		int scope = Data::skills[skill_id - 1].scope;

		if (scope == RPG::Skill::Scope_self ||
			scope == RPG::Skill::Scope_ally ||
			scope == RPG::Skill::Scope_party) {
			// ToDo: A skill is also acceptable when it cures a status
			return (Data::skills[skill_id - 1].affect_hp ||
					Data::skills[skill_id - 1].affect_sp);
		}
	} else if (Data::skills[skill_id - 1].type == RPG::Skill::Type_switch) {
		// Todo:
		// if (Game_Temp::IsInBattle()) {
		// return Data::skills[skill_id - 1].occasion_battle;
		// else {
		return Data::skills[skill_id - 1].occasion_field;
		// }
	}

	return false;
}
Example #2
0
bool Game_Battler::UseSkill(int skill_id) {
	const RPG::Skill& skill = Data::skills[skill_id - 1];

	switch (skill.type) {
		case RPG::Skill::Type_normal: {
			int effect = skill.power;

			if (skill.variance > 0) {
				int var_perc = skill.variance * 5;
				int act_perc = rand() % (var_perc * 2) - var_perc;
				int change = effect * act_perc / 100;
				effect += change;
			}

			if (skill.affect_hp) {
				ChangeHp(effect);
			}
			if (skill.affect_sp) {
				SetSp(GetSp() + effect);
			}

			// ToDo
			return true;
		}
		case RPG::Skill::Type_teleport:
		case RPG::Skill::Type_escape:
			// ToDo: Show Teleport/Escape target menu
			break;
		case RPG::Skill::Type_switch:
			Game_Switches[skill.switch_id] = true;
			break;
	}

	return false;
}
Example #3
0
void Game_Actor::SetLevel(int _level) {
	GetData().level = min(max(_level, 1), GetMaxLevel());
	// Ensure current HP/SP remain clamped if new Max HP/SP is less.
	SetHp(GetHp());
	SetSp(GetSp());

}
Example #4
0
/*
	Why is the type wrong?  Why not return (to the signal handler) for
	further diagnostics?
*/
mem_t
StackError(ucontext_t* ucontext, mem_t badadd)
{
	mem_t sp = GetSp(ucontext);

	fprintf(stderr,"\n------------------StackError---------------------\n");
	fprintf(stderr,"sp, badreference:  %lx   %lx\n",(long)sp,(long)badadd);
	DIE("stack error");
	return 0; /* NOTREACHED */
}
Example #5
0
bool Game_Enemy::IsActionValid(const RPG::EnemyAction& action) {
	if (action.kind == action.Kind_skill) {
		if (!IsSkillUsable(action.skill_id)) {
			return false;
		}
	}

	switch (action.condition_type) {
	case RPG::EnemyAction::ConditionType_always:
		return true;
	case RPG::EnemyAction::ConditionType_switch:
		return Game_Switches[action.switch_id];
	case RPG::EnemyAction::ConditionType_turn:
		{
			int turns = Game_Battle::GetTurn();
			return Game_Battle::CheckTurns(turns, action.condition_param2, action.condition_param1);
		}
	case RPG::EnemyAction::ConditionType_actors:
		{
			std::vector<Game_Battler*> battlers;
			GetParty().GetActiveBattlers(battlers);
			int count = (int)battlers.size();
			return count >= action.condition_param1 && count <= action.condition_param2;
		}
	case RPG::EnemyAction::ConditionType_hp:
		{
			int hp_percent = GetHp() * 100 / GetMaxHp();
			return hp_percent >= action.condition_param1 && hp_percent <= action.condition_param2;
		}
	case RPG::EnemyAction::ConditionType_sp:
		{
			int sp_percent = GetSp() * 100 / GetMaxSp();
			return sp_percent >= action.condition_param1 && sp_percent <= action.condition_param2;
		}
	case RPG::EnemyAction::ConditionType_party_lvl:
		{
			int party_lvl = Main_Data::game_party->GetAverageLevel();
			return party_lvl >= action.condition_param1 && party_lvl <= action.condition_param2;
		}
	case RPG::EnemyAction::ConditionType_party_fatigue:
		{
			int party_exh = Main_Data::game_party->GetFatigue();
			return party_exh >= action.condition_param1 && party_exh <= action.condition_param2;
		}
	default:
		return true;
	}
}
Example #6
0
bool Game_Battler::IsSkillUsable(int skill_id) const {
	const RPG::Skill& skill = Data::skills[skill_id - 1];

	if (CalculateSkillCost(skill_id) > GetSp()) {
		return false;
	}
	// TODO: Check for Movable(?) and Silence

	// TODO: Escape and Teleport Spells need event SetTeleportPlace and
	// SetEscapePlace first. Not sure if any game uses this...
	//if (Data::skills[skill_id - 1].type == RPG::Skill::Type_teleport) {
	//	return is_there_a_teleport_set;
	//} else if (Data::skills[skill_id - 1].type == RPG::Skill::Type_escape) {
	//	return is_there_an_escape_set;
	//} else
	if (skill.type == RPG::Skill::Type_normal ||
		skill.type >= RPG::Skill::Type_subskill) {
		int scope = skill.scope;

		if (Game_Temp::battle_running) {
			return true;
		}
		else if (scope == RPG::Skill::Scope_self ||
			scope == RPG::Skill::Scope_ally ||
			scope == RPG::Skill::Scope_party) {

			return (skill.affect_hp ||
					skill.affect_sp ||
					skill.state_effect);
		}
	} else if (skill.type == RPG::Skill::Type_switch) {
		if (Game_Temp::battle_running) {
			return skill.occasion_battle;
		}
		else {
			return skill.occasion_field;
		}
	}

	return false;
}
Example #7
0
bool Game_Battler::UseItem(int item_id) {
	const RPG::Item& item = Data::items[item_id - 1];

	if (item.type == RPG::Item::Type_medicine) {
		int hp_change = item.recover_hp_rate * GetMaxHp() / 100 + item.recover_hp;
		int sp_change = item.recover_sp_rate * GetMaxSp() / 100 + item.recover_sp;

		if (IsDead()) {
			// Check if item can revive
			if (item.state_set.empty() || !item.state_set[0]) {
				return false;
			}

			// Revive gives at least 1 Hp
			if (hp_change == 0) {
				ChangeHp(1);
			}
		} else if (item.ko_only) {
			// Must be dead
			return false;
		}

		ChangeHp(hp_change);
		SetSp(GetSp() + sp_change);

		for (std::vector<bool>::const_iterator it = item.state_set.begin();
			it != item.state_set.end(); ++it) {
			if (*it) {
				RemoveState(*it);
			}
		}

		// TODO
		return true;
	} else if (item.type == RPG::Item::Type_material) {
		// TODO
		return false;
	}

	return false;
}
Example #8
0
bool Game_Battler::IsSkillUsable(int skill_id) const {
	const RPG::Skill* skill = ReaderUtil::GetElement(Data::skills, skill_id);

	if (!skill) {
		Output::Warning("IsSkillUsable: Invalid skill ID %d", skill_id);
		return false;
	}

	if (CalculateSkillCost(skill_id) > GetSp()) {
		return false;
	}

	// > 10 makes any skill usable
	int32_t smallest_physical_rate = 11;
	int32_t smallest_magical_rate = 11;

	const std::vector<int16_t> states = GetInflictedStates();
	for (std::vector<int16_t>::const_iterator it = states.begin();
		it != states.end(); ++it) {
		// States are guaranteed to be valid
		const RPG::State& state = *ReaderUtil::GetElement(Data::states, (*it));

		if (state.restrict_skill) {
			smallest_physical_rate = std::min(state.restrict_skill_level, smallest_physical_rate);
		}

		if (state.restrict_magic) {
			smallest_magical_rate = std::min(state.restrict_magic_level, smallest_magical_rate);
		}
	}

	if (skill->physical_rate >= smallest_physical_rate) {
		return false;
	}
	if (skill->magical_rate >= smallest_magical_rate) {
		return false;
	}

	return true;
}
Example #9
0
bool Game_Battler::IsSkillUsable(int skill_id) const {
	if (skill_id <= 0 || skill_id > (int)Data::skills.size()) {
		return false;
	}

	const RPG::Skill& skill = Data::skills[skill_id - 1];

	if (CalculateSkillCost(skill_id) > GetSp()) {
		return false;
	}
	
	// > 10 makes any skill usable
	int smallest_physical_rate = 11;
	int smallest_magical_rate = 11;

	const std::vector<int16_t> states = GetInflictedStates();
	for (std::vector<int16_t>::const_iterator it = states.begin();
		it != states.end(); ++it) {
		const RPG::State& state = Data::states[(*it) - 1];

		if (state.restrict_skill) {
			smallest_physical_rate = std::min(state.restrict_skill_level, smallest_physical_rate);
		}

		if (state.restrict_magic) {
			smallest_magical_rate = std::min(state.restrict_magic_level, smallest_magical_rate);
		}
	}

	if (skill.physical_rate >= smallest_physical_rate) {
		return false;
	}
	if (skill.magical_rate >= smallest_magical_rate) {
		return false;
	}

	return true;
}
Example #10
0
bool Game_Battler::HasFullSp() const {
	return GetMaxSp() == GetSp();
}
Example #11
0
void Game_Battler::ChangeSp(int sp) {
	SetSp(GetSp() + sp);
}
Example #12
0
static int proc_start(PROCESS *prp, uintptr_t *start_ip) {
	THREAD						*thp;
	struct loader_context		*lcp = prp->lcp;

	if(!(thp = vector_lookup(&prp->threads, lcp->tid - 1)) || thp->state != STATE_REPLY) {
		return EL3HLT;
	}

	if((lcp->state & LC_STATE_MASK) == LC_FORK) {
		THREAD							*pthp;
		int								tid;
		struct _thread_local_storage	*tsp;
		char							buff[0x100];
		struct _thread_local_storage	tls;
		unsigned						size = 0;
		uintptr_t						sp;

		if(!(lookup_rcvid(0, lcp->rcvid, &pthp)) || pthp->state != STATE_REPLY) {
			return EL3HLT;
		}
		sp = GetSp(pthp);

		tid = thp->un.lcl.tls->__tid;
		tsp = thp->un.lcl.tls = pthp->un.lcl.tls;
		thp->un.lcl.stacksize = pthp->un.lcl.stacksize; 
		if(!(lcp->flags & _FORK_ASPACE)) {
			memcpy(&tls, tsp, sizeof(tls));
#ifdef STACK_GROWS_UP
			if ((size = sp - lcp->start.stackaddr) >= sizeof(buff)) return ENOMEM;
			memcpy(buff, (void *)lcp->start.stackaddr, size);
#else
			if ((size = lcp->start.stackaddr - sp) >= sizeof(buff)) return ENOMEM;
			memcpy(buff, (void *)sp, size);
#endif
		}

		KerextLock();

		tsp->__pid = prp->pid;
		tsp->__tid = tid;
		tsp->__owner = ((tsp->__pid << 16) | tsp->__tid) & ~_NTO_SYNC_WAITING;

		thp->reg = pthp->reg;
		thp->runmask = thp->default_runmask = pthp->default_runmask;

		prp->flags |= _NTO_PF_FORKED;

		if(!(lcp->flags & _FORK_ASPACE)) {
			struct vfork_info				*vip;

			if(size > sizeof buff || !(vip = prp->vfork_info = malloc(offsetof(struct vfork_info, frame) + size))) {
				return ENOMEM;
			}
			vip->rcvid = lcp->rcvid;
			vip->tls = tls;
#ifdef STACK_GROWS_UP
			vip->frame_base = (void *)lcp->start.stackaddr;
#else
			vip->frame_base = (void *)sp;
#endif
			vip->frame_size = size;
			memcpy(vip->frame, buff, size);
		}

		if(!(lcp->flags & _FORK_NOZOMBIE)) {
			prp->flags &= ~_NTO_PF_NOZOMBIE;
		}

		// Don't allow anything to change the IP
		thp->flags |= _NTO_TF_KERERR_SET;
		return EOK;
	}