Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/Abilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,11 +170,11 @@ static SkillResult handleSkillBatteryDrain(SkillData* skill, int power, ICombata
if(!blocked) {
boostDrain = (int)(skill->values[0][power] * scalingFactor);
if(boostDrain > plr->batteryW) boostDrain = plr->batteryW;
plr->batteryW -= boostDrain;
plr->subtractCapped(CappedValueType::BATTERY_W, boostDrain);

potionDrain = (int)(skill->values[1][power] * scalingFactor);
if(potionDrain > plr->batteryN) potionDrain = plr->batteryN;
plr->batteryN -= potionDrain;
plr->subtractCapped(CappedValueType::BATTERY_N, potionDrain);
}

sSkillResult_BatteryDrain result{};
Expand Down Expand Up @@ -364,7 +364,7 @@ void Abilities::useNPCSkill(EntityRef npc, int skillID, std::vector<ICombatant*>
ICombatant* src = nullptr;
if(npc.kind == EntityKind::COMBAT_NPC || npc.kind == EntityKind::MOB)
src = dynamic_cast<ICombatant*>(entity);

SkillData* skill = &SkillTable[skillID];

std::vector<SkillResult> results = handleSkill(skill, 0, src, affected);
Expand Down Expand Up @@ -443,7 +443,7 @@ std::vector<ICombatant*> Abilities::matchTargets(ICombatant* src, SkillData* ski
}
}

return targets;
return targets;
}

/* ripped from client (enums emplaced) */
Expand Down
64 changes: 49 additions & 15 deletions src/BuiltinCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,30 +75,22 @@ static void setValuePlayer(CNSocket* sock, CNPacketData* data) {
case CN_GM_SET_VALUE_TYPE__HP:
response.iSetValue = plr->HP = setData->iSetValue;
break;
case CN_GM_SET_VALUE_TYPE__WEAPON_BATTERY :
plr->batteryW = setData->iSetValue;

// caps
if (plr->batteryW > 9999)
plr->batteryW = 9999;

case CN_GM_SET_VALUE_TYPE__WEAPON_BATTERY:
plr->setCapped(CappedValueType::BATTERY_W, setData->iSetValue);
response.iSetValue = plr->batteryW;
break;
case CN_GM_SET_VALUE_TYPE__NANO_BATTERY:
plr->batteryN = setData->iSetValue;

// caps
if (plr->batteryN > 9999)
plr->batteryN = 9999;

plr->setCapped(CappedValueType::BATTERY_N, setData->iSetValue);
response.iSetValue = plr->batteryN;
break;
case CN_GM_SET_VALUE_TYPE__FUSION_MATTER:
Missions::updateFusionMatter(sock, setData->iSetValue - plr->fusionmatter);
plr->setCapped(CappedValueType::FUSIONMATTER, setData->iSetValue);
Missions::updateFusionMatter(sock);
response.iSetValue = plr->fusionmatter;
break;
case CN_GM_SET_VALUE_TYPE__CANDY:
response.iSetValue = plr->money = setData->iSetValue;
plr->setCapped(CappedValueType::TAROS, setData->iSetValue);
response.iSetValue = plr->money;
break;
case CN_GM_SET_VALUE_TYPE__SPEED:
case CN_GM_SET_VALUE_TYPE__JUMP:
Expand Down Expand Up @@ -148,6 +140,47 @@ static void setGMSpecialOnOff(CNSocket *sock, CNPacketData *data) {
// this is only used for muting players, so no need to update the client since that logic is server-side
}

static void setGMRewardRate(CNSocket *sock, CNPacketData *data) {
Player *plr = PlayerManager::getPlayer(sock);

// access check
if (plr->accountLevel > 30)
return;

auto req = (sP_CL2FE_GM_REQ_REWARD_RATE*)data->buf;

if (req->iGetSet != 0) {
double *rate = plr->rateT;

switch (req->iRewardType) {
case REWARD_TYPE_TAROS:
rate = plr->rateT;
break;
case REWARD_TYPE_FUSIONMATTER:
rate = plr->rateF;
break;
}

switch (req->iRewardRateIndex) {
case RATE_SLOT_ALL:
for (int i = 0; i < 5; i++)
rate[i] = req->iSetRateValue;
break;
case RATE_SLOT_COMBAT:
case RATE_SLOT_MISSION:
case RATE_SLOT_EGG:
case RATE_SLOT_RACING:
rate[req->iRewardRateIndex] = req->iSetRateValue;
break;
}
}

INITSTRUCT(sP_FE2CL_GM_REP_REWARD_RATE_SUCC, resp);
memcpy(resp.afRewardRate_Taros, plr->rateT, sizeof(resp.afRewardRate_Taros));
memcpy(resp.afRewardRate_FusionMatter, plr->rateF, sizeof(resp.afRewardRate_FusionMatter));
sock->sendPacket(resp, P_FE2CL_GM_REP_REWARD_RATE_SUCC);
}

static void locatePlayer(CNSocket *sock, CNPacketData *data) {
Player *plr = PlayerManager::getPlayer(sock);

Expand Down Expand Up @@ -371,6 +404,7 @@ void BuiltinCommands::init() {

REGISTER_SHARD_PACKET(P_CL2FE_GM_REQ_PC_SPECIAL_STATE_SWITCH, setGMSpecialSwitchPlayer);
REGISTER_SHARD_PACKET(P_CL2FE_GM_REQ_TARGET_PC_SPECIAL_STATE_ONOFF, setGMSpecialOnOff);
REGISTER_SHARD_PACKET(P_CL2FE_GM_REQ_REWARD_RATE, setGMRewardRate);

REGISTER_SHARD_PACKET(P_CL2FE_GM_REQ_PC_LOCATION, locatePlayer);
REGISTER_SHARD_PACKET(P_CL2FE_GM_REQ_KICK_PLAYER, kickPlayer);
Expand Down
15 changes: 4 additions & 11 deletions src/Combat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ EntityRef CombatNPC::getRef() {
}

void CombatNPC::step(time_t currTime) {

if(stateHandlers.find(state) != stateHandlers.end())
stateHandlers[state](this, currTime);
else {
Expand Down Expand Up @@ -441,11 +441,7 @@ static void pcAttackNpcs(CNSocket *sock, CNPacketData *data) {
damage = getDamage(damage.first, (int)mob->data["m_iProtection"], true, (plr->batteryW > 6 + difficulty),
Nanos::nanoStyle(plr->activeNano), (int)mob->data["m_iNpcStyle"], difficulty);

if (plr->batteryW >= 6 + difficulty)
plr->batteryW -= 6 + difficulty;
else
plr->batteryW = 0;

plr->subtractCapped(CappedValueType::BATTERY_W, 6 + difficulty);
damage.first = mob->takeDamage(sock, damage.first);

respdata[i].iID = mob->id;
Expand Down Expand Up @@ -690,10 +686,7 @@ static void pcAttackChars(CNSocket *sock, CNPacketData *data) {
Nanos::nanoStyle(plr->activeNano), (int)mob->data["m_iNpcStyle"], difficulty);
}

if (plr->batteryW >= 6 + plr->level)
plr->batteryW -= 6 + plr->level;
else
plr->batteryW = 0;
plr->subtractCapped(CappedValueType::BATTERY_W, 6 + plr->level);

damage.first = target->takeDamage(sock, damage.first);

Expand Down Expand Up @@ -742,7 +735,7 @@ static int8_t addBullet(Player* plr, bool isGrenade) {
toAdd.weaponBoost = plr->batteryW > 0;
if (toAdd.weaponBoost) {
int boostCost = Rand::rand(11) + 20;
plr->batteryW = boostCost > plr->batteryW ? 0 : plr->batteryW - boostCost;
plr->subtractCapped(CappedValueType::BATTERY_W, boostCost);
}

Bullets[plr->iID][findId] = toAdd;
Expand Down
6 changes: 3 additions & 3 deletions src/Email.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ static void emailReceiveTaros(CNSocket* sock, CNPacketData* data) {

Database::EmailData email = Database::getEmail(plr->iID, pkt->iEmailIndex);
// money transfer
plr->money += email.Taros;
plr->addCapped(CappedValueType::TAROS, email.Taros);
email.Taros = 0;
// update Taros in email
Database::updateEmailContent(&email);
Expand Down Expand Up @@ -274,7 +274,7 @@ static void emailSend(CNSocket* sock, CNPacketData* data) {
}

int cost = pkt->iCash + 50 + 20 * attachments.size(); // attached taros + postage
plr->money -= cost;
plr->subtractCapped(CappedValueType::TAROS, cost);
Database::EmailData email = {
(int)pkt->iTo_PCUID, // PlayerId
Database::getNextEmailIndex(pkt->iTo_PCUID), // MsgIndex
Expand All @@ -291,7 +291,7 @@ static void emailSend(CNSocket* sock, CNPacketData* data) {
};

if (!Database::sendEmail(&email, attachments, plr)) {
plr->money += cost; // give money back
plr->addCapped(CappedValueType::TAROS, cost); // give money back
// give items back
while (!attachments.empty()) {
sItemBase attachment = attachments.back();
Expand Down
106 changes: 106 additions & 0 deletions src/Entities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,112 @@ sPCAppearanceData Player::getAppearanceData() {
return data;
}

bool Player::hasQuestBoost() const {
const sItemBase& booster = Equip[10];
return booster.iID == 153 && booster.iOpt > 0;
}

bool Player::hasHunterBoost() const {
const sItemBase& booster = Equip[11];
return booster.iID == 154 && booster.iOpt > 0;
}

bool Player::hasRacerBoost() const {
const sItemBase& booster = Equip[9];
return booster.iID == 155 && booster.iOpt > 0;
}

bool Player::hasSuperBoost() const {
return Player::hasQuestBoost() && Player::hasHunterBoost() && Player::hasRacerBoost();
}

static int32_t getCap(CappedValueType type) {
switch (type) {
case CappedValueType::TAROS:
return PC_CANDY_MAX;
case CappedValueType::FUSIONMATTER:
return PC_FUSIONMATTER_MAX;
case CappedValueType::BATTERY_W:
return PC_BATTERY_MAX;
case CappedValueType::BATTERY_N:
return PC_BATTERY_MAX;
case CappedValueType::TAROS_IN_TRADE:
return PC_CANDY_MAX;
default:
return INT32_MAX;
}
}

static int32_t *getCappedValue(Player *player, CappedValueType type) {
switch (type) {
case CappedValueType::TAROS:
return &player->money;
case CappedValueType::FUSIONMATTER:
return &player->fusionmatter;
case CappedValueType::BATTERY_W:
return &player->batteryW;
case CappedValueType::BATTERY_N:
return &player->batteryN;
case CappedValueType::TAROS_IN_TRADE:
return &player->moneyInTrade;
default:
return nullptr;
}
}

void Player::addCapped(CappedValueType type, int32_t diff) {
if (diff <= 0)
return;

int32_t max = getCap(type);
int32_t *value = getCappedValue(this, type);

if (value == nullptr)
return;

if (diff > max)
diff = max;

if (*value + diff > max)
*value = max;
else
*value += diff;
}

void Player::subtractCapped(CappedValueType type, int32_t diff) {
if (diff <= 0)
return;

int32_t max = getCap(type);
int32_t *value = getCappedValue(this, type);

if (value == nullptr)
return;

if (diff > max)
diff = max;

if (*value - diff < 0)
*value = 0;
else
*value -= diff;
}

void Player::setCapped(CappedValueType type, int32_t value) {
int32_t max = getCap(type);
int32_t *valToSet = getCappedValue(this, type);

if (valToSet == nullptr)
return;

if (value < 0)
value = 0;
else if (value > max)
value = max;

*valToSet = value;
}

// TODO: this is less effiecient than it was, because of memset()
void Player::enterIntoViewOf(CNSocket *sock) {
INITSTRUCT(sP_FE2CL_PC_NEW, pkt);
Expand Down
Loading