Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
14 changes: 7 additions & 7 deletions source/source/content/mob/bridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ bool Bridge::checkHealth() {
for(size_t m = 0; m < newMobs.size(); m++) {
Mob* mPtr = newMobs[m];
enableFlag(mPtr->flags, MOB_FLAG_CAN_MOVE_MIDAIR);
mPtr->links.push_back(this);
mPtr->push_anonymous_link(this);
}

//Move the bridge object proper to the farthest point of the bridge.
Expand All @@ -233,15 +233,15 @@ bool Bridge::checkHealth() {
* @param m Bridge component mob.
*/
void Bridge::drawComponent(Mob* m) {
if(m->links.empty() || !m->links[0]) return;
if(m->link_anon_size==0 || !m->links["0"]) return;

BitmapEffect eff;
m->getSpriteBitmapEffects(
nullptr, nullptr, 0.0f, &eff,
SPRITE_BMP_EFFECT_FLAG_SECTOR_BRIGHTNESS
);

Bridge* briPtr = (Bridge*) m->links[0];
Bridge* briPtr = (Bridge*) m->links["0"];
string side = m->vars["side"];
ALLEGRO_BITMAP* texture =
side == "left" ?
Expand Down Expand Up @@ -346,10 +346,10 @@ void Bridge::readScriptVars(const ScriptVarReader &svr) {
* like its linked destination object.
*/
void Bridge::setup() {
if(!links.empty() && links[0]) {
totalLength = Distance(pos, links[0]->pos).toFloat();
face(getAngle(pos, links[0]->pos), nullptr, true);
deltaZ = links[0]->z - z;
if(!link_anon_size == 0 && links["0"]) {
totalLength = Distance(pos, links["0"]->pos).toFloat();
face(getAngle(pos, links["0"]->pos), nullptr, true);
deltaZ = links["0"]->z - z;
totalChunksNeeded =
std::max(
totalChunksNeeded,
Expand Down
62 changes: 39 additions & 23 deletions source/source/content/mob/mob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,13 @@ void Mob::addToGroup(Mob* newMember) {
}
}

/**
* @brief counts the number of non identified links
*/
void Mob::push_anonymous_link(Mob* linkPtr) {
links[i2s(link_anon_size)]= linkPtr;
link_anon_size +=1;
}

/**
* @brief Applies the damage caused by an attack from another mob to this one.
Expand Down Expand Up @@ -451,18 +458,21 @@ void Mob::arachnorbHeadTurnLogic() {
float angleDeviationAvg = 0;
size_t nFeet = 0;

for(size_t l = 0; l < links.size(); l++) {
if(!links[l]) {
for (const auto& [identifier, link] : links) {
if (!isNumber(identifier)){
continue;
}
if(!link) {
continue;
}

if(!links[l]->parent) {
if(!link->parent) {
continue;
}
if(links[l]->parent->m != this) {
if(link->parent->m != this) {
continue;
}
if(links[l]->parent->limbParentBodyPart == INVALID) {
if(link->parent->limbParentBodyPart == INVALID) {
continue;
}

Expand All @@ -472,11 +482,11 @@ void Mob::arachnorbHeadTurnLogic() {
getAngle(
Point(),
getHitbox(
links[l]->parent->limbParentBodyPart
link->parent->limbParentBodyPart
)->pos
);
float curAngle =
getAngle(pos, links[l]->pos) - angle;
getAngle(pos, link->pos) - angle;
float angleDeviation =
getAngleCwDiff(defaultAngle, curAngle);
if(angleDeviation > M_PI) {
Expand Down Expand Up @@ -664,12 +674,14 @@ bool Mob::calculateCarryingDestination(
//If it's towards a linked mob, just go to the closest one.
Mob* closestLink = nullptr;
Distance closestLinkDist;

for(size_t s = 0; s < links.size(); s++) {
Distance d(pos, links[s]->pos);
for (const auto& [identifier, link] : links) {
if (!isNumber(identifier)){
continue;
}
Distance d(pos, link->pos);

if(!closestLink || d < closestLinkDist) {
closestLink = links[s];
closestLink = link;
closestLinkDist = d;
}
}
Expand All @@ -692,12 +704,15 @@ bool Mob::calculateCarryingDestination(
}

unordered_set<PikminType*> availableTypes;
vector<std::pair<Mob*, PikminType*> > mobsPerType;
vector<std::pair<string, PikminType*> > mobsPerType;

for(size_t l = 0; l < links.size(); l++) {
if(!links[l]) continue;
for (const auto& [identifier, link] : links) {
if (!isNumber(identifier)){
continue;
}
if(!link) continue;
string typeName =
links[l]->vars["carry_destination_type"];
link->vars["carry_destination_type"];
MobType* pikType =
game.mobCategories.get(MOB_CATEGORY_PIKMIN)->
getType(typeName);
Expand All @@ -707,7 +722,7 @@ bool Mob::calculateCarryingDestination(
(PikminType*) pikType
);
mobsPerType.push_back(
std::make_pair(links[l], (PikminType*) pikType)
std::make_pair(identifier,(PikminType*) pikType)
);
}

Expand All @@ -720,21 +735,21 @@ bool Mob::calculateCarryingDestination(
decideCarryPikminType(availableTypes, added, removed);

//Figure out which linked mob matches the decided type.
size_t closestTargetIdx = INVALID;
string closestTargetKey = "";
Distance closestTargetDist;
for(size_t m = 0; m < mobsPerType.size(); m++) {
if(mobsPerType[m].second != decidedType) continue;

Distance d(pos, mobsPerType[m].first->pos);
if(closestTargetIdx == INVALID || d < closestTargetDist) {
Distance d(pos, links.at(mobsPerType[m].first)->pos);
if(closestTargetKey.empty() || d < closestTargetDist) {
closestTargetDist = d;
closestTargetIdx = m;
closestTargetKey = mobsPerType[m].first;
}
}

//Finally, set the destination data.
*targetType = decidedType;
*targetMob = links[closestTargetIdx];
*targetMob = links.at(closestTargetKey);
*targetPoint = (*targetMob)->pos;

return true;
Expand Down Expand Up @@ -1591,6 +1606,7 @@ void Mob::focusOnMob(Mob* m2) {
}



/**
* @brief Makes the mob start following a path. This populates the pathInfo
* class member, and calculates a path to take.
Expand Down Expand Up @@ -3296,10 +3312,10 @@ Mob* Mob::spawn(const MobType::SpawnInfo* info, MobType* typePtr) {
}

if(info->linkObjectToSpawn) {
links.push_back(newMob);
push_anonymous_link(newMob);
}
if(info->linkSpawnToObject) {
newMob->links.push_back(this);
newMob->push_anonymous_link(this);
}
if(info->momentum != 0) {
float a = game.rng.f(0, TAU);
Expand Down
6 changes: 5 additions & 1 deletion source/source/content/mob/mob.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,8 +255,11 @@ class Mob {
//-Interactions with other mobs-

//Mobs it is linked to.
vector<Mob*> links;
map<string,Mob*> links;

//How many Anonymous Links there are
size_t link_anon_size=0;

//If it's being held by another mob, the information is kept here.
HoldInfo holder;

Expand Down Expand Up @@ -375,6 +378,7 @@ class Mob {
void becomeCarriable(const CARRY_DESTINATION destination);
void becomeUncarriable();

void push_anonymous_link(Mob* linkPtr);
void applyAttackDamage(
Mob* attacker, Hitbox* attackH, Hitbox* victimH, float damage
);
Expand Down
6 changes: 3 additions & 3 deletions source/source/content/mob/mob_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1272,9 +1272,9 @@ void deleteMob(Mob* mPtr, bool completeDestruction) {
m2Ptr->chompingMobs[c] = nullptr;
}
}
for(size_t l = 0; l < m2Ptr->links.size(); l++) {
if(m2Ptr->links[l] == mPtr) {
m2Ptr->links[l] = nullptr;
for (const auto& [identifier, link] : m2Ptr->links) {
if(link == mPtr) {
m2Ptr->links[identifier] = nullptr;
}
}
if(m2Ptr->storedInsideAnother == mPtr) {
Expand Down
4 changes: 2 additions & 2 deletions source/source/content/mob/pikmin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -587,8 +587,8 @@ void Pikmin::tickClassSpecifics(float deltaT) {
bumpLock = std::max(bumpLock - deltaT, 0.0f);

//Forcefully follow another mob as a leader.
if(mustFollowLinkAsLeader && !links.empty()) {
Mob* leader = links[0];
if(mustFollowLinkAsLeader && !link_anon_size == 0 && links["0"]) {
Mob* leader = links["0"];
fsm.runEvent(
MOB_EV_TOUCHED_ACTIVE_LEADER,
(void*) (leader),
Expand Down
4 changes: 2 additions & 2 deletions source/source/content/mob_script/bouncer_fsm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ void BouncerFsm::handleMob(Mob* m, void* info1, void* info2) {
Mob* toucher = (Mob*) info1;
Mob* targetMob = nullptr;

if(!bouPtr->links.empty()) {
targetMob = bouPtr->links[0];
if(!bouPtr->link_anon_size ==0 && bouPtr->links["0"]) {
targetMob = bouPtr->links["0"];
}

if(!targetMob) {
Expand Down
58 changes: 35 additions & 23 deletions source/source/content/other/mob_script_action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -440,9 +440,12 @@ bool MobActionLoaders::loadMobTargetType(
call.args[argIdx] = i2s(MOB_ACTION_MOB_TARGET_TYPE_FOCUS);
} else if(call.args[argIdx] == "trigger") {
call.args[argIdx] = i2s(MOB_ACTION_MOB_TARGET_TYPE_TRIGGER);
} else if(call.args[argIdx] == "link") {
} else if(call.args[argIdx].find("link")==0) {
call.args.resize(17,"");
call.args[16]= call.args[argIdx].substr(4);
call.args[argIdx] = i2s(MOB_ACTION_MOB_TARGET_TYPE_LINK);
} else if(call.args[argIdx] == "parent") {
}
else if(call.args[argIdx] == "parent") {
call.args[argIdx] = i2s(MOB_ACTION_MOB_TARGET_TYPE_PARENT);
} else {
reportEnumError(call, argIdx);
Expand Down Expand Up @@ -1349,8 +1352,12 @@ Mob* getTargetMob(
return getTriggerMob(data);
break;
} case MOB_ACTION_MOB_TARGET_TYPE_LINK: {
if(!data.m->links.empty() && data.m->links[0]) {
return data.m->links[0];

if(data.args[16] == "" && !data.m->link_anon_size ==0 && data.m->links.find("0")!= data.m->links.end() && data.m->links["0"]) {
return data.m->links["0"];
}
if(data.args[16] != "" && data.m->links.find(data.args[16]) != data.m->links.end()){
return data.m->links[data.args[16]];
}
break;
} case MOB_ACTION_MOB_TARGET_TYPE_PARENT: {
Expand Down Expand Up @@ -1441,14 +1448,17 @@ void MobActionRunners::linkWithFocus(MobActionRunData &data) {
return;
}

for(size_t l = 0; l < data.m->links.size(); l++) {
if(data.m->links[l] == data.m->focusedMob) {
for (const auto& [identifier, link] : data.m->links) {
if(link == data.m->focusedMob) {
//Already linked.
return;
}
}

data.m->links.push_back(data.m->focusedMob);
if (data.args.size() <= 0){
data.m->push_anonymous_link(data.m->focusedMob);
}else{
data.m->links[data.args[0]] = data.m->focusedMob;
}
}


Expand Down Expand Up @@ -1543,9 +1553,9 @@ void MobActionRunners::moveToTarget(MobActionRunData &data) {
}

Point des;
for(size_t l = 0; l < data.m->links.size(); l++) {
if(!data.m->links[l]) continue;
des += data.m->links[l]->pos;
for (const auto& [identifier, link] : data.m->links) {
if(!link) continue;
des += link->pos;
}
des = des / data.m->links.size();

Expand Down Expand Up @@ -1671,10 +1681,12 @@ void MobActionRunners::sendMessageToFocus(MobActionRunData &data) {
* @param data Data about the action call.
*/
void MobActionRunners::sendMessageToLinks(MobActionRunData &data) {
for(size_t l = 0; l < data.m->links.size(); l++) {
if(data.m->links[l] == data.m) continue;
if(!data.m->links[l]) continue;
data.m->sendScriptMessage(data.m->links[l], data.args[0]);
string receipient = data.args.size() > 1? data.args[1] : "0";
for (const auto& [identifier, link] : data.m->links) {
if(link == data.m) continue;
if(!link) continue;
if(receipient != "0" && identifier != receipient) continue;
data.m->sendScriptMessage(link, data.args[0]);
}
}

Expand Down Expand Up @@ -2002,28 +2014,28 @@ void MobActionRunners::spawn(MobActionRunData &data) {
* @param data Data about the action call.
*/
void MobActionRunners::stabilizeZ(MobActionRunData &data) {
if(data.m->links.empty() || !data.m->links[0]) {
if(data.m->links.empty() || !data.m->links.begin()->second) {
return;
}

float bestMatchZ = data.m->links[0]->z;
float bestMatchZ = data.m->links.begin()->second->z;
MOB_ACTION_STABILIZE_Z_TYPE t =
(MOB_ACTION_STABILIZE_Z_TYPE) s2i(data.args[0]);

for(size_t l = 1; l < data.m->links.size(); l++) {
for (const auto& [identifier, link] : data.m->links) {

if(!data.m->links[l]) continue;
if(!link) continue;

switch(t) {
case MOB_ACTION_STABILIZE_Z_TYPE_HIGHEST: {
if(data.m->links[l]->z > bestMatchZ) {
bestMatchZ = data.m->links[l]->z;
if(link->z > bestMatchZ) {
bestMatchZ = link->z;
}
break;

} case MOB_ACTION_STABILIZE_Z_TYPE_LOWEST: {
if(data.m->links[l]->z < bestMatchZ) {
bestMatchZ = data.m->links[l]->z;
if(link->z < bestMatchZ) {
bestMatchZ = link->z;
}
break;

Expand Down
2 changes: 2 additions & 0 deletions source/source/core/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1298,6 +1298,7 @@ void initMobActions() {
nullptr
);

regParam("identifier", MOB_ACTION_PARAM_STRING, false, true);
regAction(
MOB_ACTION_LINK_WITH_FOCUS,
"link_with_focused_mob",
Expand Down Expand Up @@ -1414,6 +1415,7 @@ void initMobActions() {
);

regParam("message", MOB_ACTION_PARAM_STRING, false, false);
regParam("identifier", MOB_ACTION_PARAM_STRING, false, true);
regAction(
MOB_ACTION_SEND_MESSAGE_TO_LINKS,
"send_message_to_links",
Expand Down
2 changes: 1 addition & 1 deletion source/source/game_state/gameplay/gameplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -929,7 +929,7 @@ void GameplayState::load() {
for(size_t l = 0; l < genPtr->linkIdxs.size(); l++) {
size_t linkTargetGenIdx = genPtr->linkIdxs[l];
Mob* linkTargetMobPtr = mobsPerGen[linkTargetGenIdx];
mobPtr->links.push_back(linkTargetMobPtr);
mobPtr->push_anonymous_link(linkTargetMobPtr);
}
}

Expand Down