Skip to content

Commit

Permalink
Brainsucker Progress #1
Browse files Browse the repository at this point in the history
  • Loading branch information
Istrebitel committed Mar 11, 2017
1 parent 63d6a45 commit 1e86362
Show file tree
Hide file tree
Showing 20 changed files with 861 additions and 564 deletions.
16 changes: 16 additions & 0 deletions data/common_patch/gamestate/agent_equipment.xml
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<agent_equipment>

AEQUIPMENT_BRAINSUCKER_WEAPON
<entry>
<key>AEQUIPMENTTYPE_MEGAPOL_LAWPISTOL_CLIP</key>
<value>
<max_ammo>9001</max_ammo>
<damage>9001</damage>
</value>
</entry>
<entry>
<key>AEQUIPMENTTYPE_BRAINSUCKER_WEAPON</key>
<value>
<type>Brainsucker</type>
<id>AEQUIPMENTTYPE_X-AEQUIPMENTTYPE_BRAINSUCKER_WEAPON</id>
<name>Attack</name>
<equipscreen_sprite>PCK:xcom3/ufodata/contico.pck:xcom3/ufodata/contico.tab:1:xcom3/tacdata/tactical.pal</equipscreen_sprite>
<equipscreen_size>
<x>2</x>
<y>5</y>
</equipscreen_size>
<manufacturer>ORG_X-COM</manufacturer>
</value>
</entry>
<entry>
<key>AEQUIPMENTTYPE_X-COM_BASE_TURRET_LASER</key>
<value>
Expand Down
30 changes: 28 additions & 2 deletions game/state/aequipment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,8 +330,22 @@ void AEquipment::update(GameState &state, unsigned int ticks)
}
case TriggerType::Proximity:
case TriggerType::Boomeroid:
// Nothing, triggered by moving units
{
auto item = ownerItem.lock();
if (item)
{
// Nothing, triggered by moving units
}
else
{
// Proxy trigger in inventory? Blow up!
if (payload->damage_type->effectType != DamageType::EffectType::Brainsucker)
{
explode(state);
}
}
break;
}
case TriggerType::Timed:
{
auto item = ownerItem.lock();
Expand Down Expand Up @@ -402,6 +416,11 @@ void AEquipment::explode(GameState &state)
case AEquipmentType::Type::Ammo:
{
auto payload = getPayloadType();
// If brainsucker then nothing
if (payload->damage_type->effectType == DamageType::EffectType::Brainsucker)
{
break;
}
// If explosive just blow up
if (payload->damage_type->explosive)
{
Expand Down Expand Up @@ -472,7 +491,14 @@ void AEquipment::fire(GameState &state, Vec3<float> targetPosition, StateRef<Bat
auto item = mksp<AEquipment>();
item->type = payload;
item->ammo = 1;
item->prime();
if (payload->damage_type->effectType == DamageType::EffectType::Brainsucker)
{
item->prime(false, TICKS_PER_TURN, 10.0f);
}
else
{
item->prime();
}
item->ownerUnit = ownerAgent->unit;
float velocityXY = 0.0f;
float velocityZ = 0.0f;
Expand Down
3 changes: 2 additions & 1 deletion game/state/agent.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ enum class MovementState
None,
Normal,
Running,
Strafing
Strafing,
Brainsucker
};
enum class AEquipmentSlotType
{
Expand Down
13 changes: 13 additions & 0 deletions game/state/battle/battleitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "game/state/aequipment.h"
#include "game/state/battle/battle.h"
#include "game/state/battle/battlemappart.h"
#include "game/state/battle/battlecommonsamplelist.h"
#include "game/state/battle/battleunit.h"
#include "game/state/gamestate.h"
#include "game/state/rules/aequipment_type.h"
Expand All @@ -27,6 +28,18 @@ void BattleItem::die(GameState &state, bool violently)
{
item->explode(state);
}
else if (item->getPayloadType()->damage_type->effectType == DamageType::EffectType::Brainsucker)
{
// Sound for hatching
if (state.battle_common_sample_list->brainsuckerHatch)
{
fw().soundBackend->playSample(state.battle_common_sample_list->brainsuckerHatch,
position, 0.25f);
}
LogWarning("Hatched! Spawn brainsucker!");
// spawn: throwing body facing 0,1
// set mission stand up
}
auto this_shared = shared_from_this();
state.current_battle->items.remove(this_shared);
this->tileObject->removeFromMap();
Expand Down
32 changes: 30 additions & 2 deletions game/state/battle/battleunit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1001,7 +1001,7 @@ void BattleUnit::dealDamage(GameState &state, int damage, bool generateFatalWoun
if (isDead())
{
LogWarning("Handle violent deaths");
die(state, true);
die(state);
return;
}
else if (!isConscious() && wasConscious)
Expand Down Expand Up @@ -2540,6 +2540,8 @@ void BattleUnit::update(GameState &state, unsigned int ticks)
updatePsi(state, ticks);
// AI
updateAI(state, ticks);
// Who else? :)
triggerBrainsuckers(state);
}

void BattleUnit::triggerProximity(GameState &state)
Expand All @@ -2555,7 +2557,8 @@ void BattleUnit::triggerProximity(GameState &state)
// Proximity explosion trigger
if ((i->item->triggerType == TriggerType::Proximity ||
i->item->triggerType == TriggerType::Boomeroid) &&
BattleUnitTileHelper::getDistanceStatic(position, i->position) <= i->item->triggerRange)
BattleUnitTileHelper::getDistanceStatic(position, i->position) <= i->item->triggerRange &&
i->item->getPayloadType()->damage_type->effectType != DamageType::EffectType::Brainsucker)
{
i->die(state);
}
Expand All @@ -2568,6 +2571,30 @@ void BattleUnit::triggerProximity(GameState &state)
}
}

void BattleUnit::triggerBrainsuckers(GameState &state)
{
StateRef<DamageType> brainsucker = { &state, "DAMAGETYPE_BRAINSUCKER" };
if (brainsucker->dealDamage(100, agent->type->damage_modifier) == 0)
return;

auto it = state.current_battle->items.begin();
while (it != state.current_battle->items.end())
{
auto i = *it++;
if (!i->item->primed || i->item->triggerDelay > 0)
{
continue;
}
if (i->item->triggerType == TriggerType::Proximity &&
BattleUnitTileHelper::getDistanceStatic(position, i->position) <= i->item->triggerRange &&
i->item->getPayloadType()->damage_type->effectType == DamageType::EffectType::Brainsucker &&
i->item->ownerUnit->owner->isRelatedTo(owner) == Organisation::Relation::Hostile)
{
i->die(state);
}
}
}

void BattleUnit::startFalling()
{
setMovementState(MovementState::None);
Expand Down Expand Up @@ -2986,6 +3013,7 @@ void BattleUnit::retreat(GameState &state)

void BattleUnit::die(GameState &state, bool violently, bool bledToDeath)
{
agent->modified_stats.health = 0;
std::ignore = bledToDeath;
if (violently)
{
Expand Down
3 changes: 2 additions & 1 deletion game/state/battle/battleunit.h
Original file line number Diff line number Diff line change
Expand Up @@ -494,11 +494,12 @@ class BattleUnit : public StateObject, public std::enable_shared_from_this<Battl
void updateAI(GameState &state, unsigned int ticks);

void triggerProximity(GameState &state);
void triggerBrainsuckers(GameState &state);
void retreat(GameState &state);
void dropDown(GameState &state);
void tryToRiseUp(GameState &state);
void fallUnconscious(GameState &state);
void die(GameState &state, bool violently, bool bledToDeath = false);
void die(GameState &state, bool violently = true, bool bledToDeath = false);

// Following members are not serialized, but rather are set in initBattle method

Expand Down
2 changes: 1 addition & 1 deletion game/state/battle/battleunitmission.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1434,7 +1434,7 @@ bool BattleUnitMission::isFinishedInternal(GameState &, BattleUnit &u)

void BattleUnitMission::start(GameState &state, BattleUnit &u)
{
LogWarning("Unit mission \"%s\" starting", getName());
LogWarning("Unit %s mission \"%s\" starting", u.id, getName());

switch (this->type)
{
Expand Down
3 changes: 3 additions & 0 deletions game/state/gamestate_serialize.xml
Original file line number Diff line number Diff line change
Expand Up @@ -785,6 +785,7 @@
<value>Smoke</value>
<value>Fire</value>
<value>Enzyme</value>
<value>Brainsucker</value>
</enum>
<object>
<name>DamageType</name>
Expand Down Expand Up @@ -1329,6 +1330,7 @@
<value>CloakingField</value>
<value>DimensionForceField</value>
<value>MediKit</value>
<value>Brainsucker</value>
<value>Loot</value>
</enum>
<enum>
Expand Down Expand Up @@ -1404,6 +1406,7 @@
<value>Normal</value>
<value>Running</value>
<value>Strafing</value>
<value>Brainsucker</value>
</enum>
<enum>
<name>AIType</name>
Expand Down
2 changes: 2 additions & 0 deletions game/state/rules/aequipment_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ class AEquipmentType : public StateObject
CloakingField,
DimensionForceField,
MediKit,
// This is not in the game files, but we need it to function
Brainsucker,
// For Psi-clones and stuff
Loot
};
Expand Down
3 changes: 2 additions & 1 deletion game/state/rules/damage.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ class DamageType : public StateObject
Stun,
Smoke,
Fire,
Enzyme
Enzyme,
Brainsucker
};

bool ignore_shield = false;
Expand Down
19 changes: 18 additions & 1 deletion game/ui/battle/battleview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1793,7 +1793,8 @@ void BattleView::eventOccurred(Event *e)
e->keyboard().KeyCode == SDLK_LALT || e->keyboard().KeyCode == SDLK_RCTRL ||
e->keyboard().KeyCode == SDLK_LCTRL || e->keyboard().KeyCode == SDLK_f ||
e->keyboard().KeyCode == SDLK_r || e->keyboard().KeyCode == SDLK_a
|| e->keyboard().KeyCode == SDLK_p || e->keyboard().KeyCode == SDLK_h))
|| e->keyboard().KeyCode == SDLK_p || e->keyboard().KeyCode == SDLK_h
|| e->keyboard().KeyCode == SDLK_k))
{
switch (e->keyboard().KeyCode)
{
Expand Down Expand Up @@ -1869,6 +1870,22 @@ void BattleView::eventOccurred(Event *e)
revealWholeMap = !revealWholeMap;
break;
}
case SDLK_k:
{
for (auto &u : battle.units)
{
if (u.second->isDead())
{
continue;
}

if (u.second->tileObject->getOwningTile()->position == selectedTilePosition)
{
u.second->die(*state);
}
}
break;
}
case SDLK_p:
{
LogWarning("Panic mode engaged!");
Expand Down
2 changes: 2 additions & 0 deletions tools/extractor.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
<ClCompile Include="extractors\extractors.cpp" />
<ClCompile Include="extractors\extract_agent_equipment.cpp" />
<ClCompile Include="extractors\extract_agent_types.cpp" />
<ClCompile Include="extractors\extract_animation_pack_template.cpp" />
<ClCompile Include="extractors\extract_base_layouts.cpp" />
<ClCompile Include="extractors\extract_battlescape_map.cpp" />
<ClCompile Include="extractors\extract_battlescape_map_parts.cpp" />
Expand All @@ -38,6 +39,7 @@
<ClCompile Include="extractors\extract_organisations.cpp" />
<ClCompile Include="extractors\extract_research.cpp" />
<ClCompile Include="extractors\extract_unit_animation_packs.cpp" />
<ClCompile Include="extractors\extract_unit_animation_pack_bsk.cpp" />
<ClCompile Include="extractors\extract_unit_animation_pack_unit.cpp" />
<ClCompile Include="extractors\extract_unit_image_packs.cpp" />
<ClCompile Include="extractors\extract_vehicles.cpp" />
Expand Down
6 changes: 6 additions & 0 deletions tools/extractor.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@
<ClCompile Include="extractors\extract_doodads.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="extractors\extract_unit_animation_pack_bsk.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="extractors\extract_animation_pack_template.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="extractors\extractors.h">
Expand Down
20 changes: 18 additions & 2 deletions tools/extractors/extract_agent_equipment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@
#define DT_BRAINSUCKER 18
#define DT_ENTROPY 16

#define DM_HUMAN 0
#define DM_MUTANT 1

namespace OpenApoc
{

Expand Down Expand Up @@ -301,6 +304,9 @@ void InitialGameStateExtractor::extractAgentEquipment(GameState &state) const
d->explosive = true;
d->blockType = DamageType::BlockType::Psionic;
break;
case DT_BRAINSUCKER:
d->effectType = DamageType::EffectType::Brainsucker;
break;
}

state.damage_types[id] = d;
Expand Down Expand Up @@ -348,6 +354,9 @@ void InitialGameStateExtractor::extractAgentEquipment(GameState &state) const
->modifiers[{&state, id}] = ddata.damage_type_data[j];
}
}

state.damage_types[data_t.getDTypeId(DT_BRAINSUCKER)]->modifiers[{&state, id}] =
(i == DM_HUMAN || i == DM_MUTANT) ? 100 : 0;
}

for (unsigned i = 0; i < data_t.agent_equipment->count(); i++)
Expand Down Expand Up @@ -863,8 +872,14 @@ void InitialGameStateExtractor::extractAgentEquipment(GameState &state) const
{
e->damage_type = { &state, data_t.getDTypeId(pdata.damage_type) };
}
switch (pdata.trigger_type)
if (id == "AEQUIPMENTTYPE_BRAINSUCKER_POD")
{
e->trigger_type = TriggerType::Proximity;
}
else
{
switch (pdata.trigger_type)
{
case AGENT_GRENADE_TRIGGER_TYPE_NORMAL:
e->trigger_type = TriggerType::Timed;
break;
Expand All @@ -876,7 +891,8 @@ void InitialGameStateExtractor::extractAgentEquipment(GameState &state) const
break;
default:
LogError("Unexpected grenade trigger type %d for ID %s",
(int)pdata.trigger_type, id);
(int)pdata.trigger_type, id);
}
}
e->explosion_depletion_rate = pdata.explosion_depletion_rate;

Expand Down
Loading

0 comments on commit 1e86362

Please sign in to comment.