Index: binaries/data/mods/public/simulation/components/Attack.js
===================================================================
--- binaries/data/mods/public/simulation/components/Attack.js
+++ binaries/data/mods/public/simulation/components/Attack.js
@@ -403,15 +403,22 @@
return aPreference - bPreference;
};
-Attack.prototype.GetTimers = function(type)
+Attack.prototype.GetRepeatTime = function(type)
{
- let prepare = +(this.template[type].PrepareTime || 0);
- prepare = ApplyValueModificationsToEntity("Attack/" + type + "/PrepareTime", prepare, this.entity);
+ let repeatTime = 1000;
+
+ if (this.template[type] && this.template[type].RepeatTime)
+ repeatTime = +this.template[type].RepeatTime;
- let repeat = +(this.template[type].RepeatTime || 1000);
- repeat = ApplyValueModificationsToEntity("Attack/" + type + "/RepeatTime", repeat, this.entity);
+ return ApplyValueModificationsToEntity("Attack/" + type + "/RepeatTime", repeatTime, this.entity);
+};
- return { "prepare": prepare, "repeat": repeat };
+Attack.prototype.GetTimers = function(type)
+{
+ return {
+ "prepare": ApplyValueModificationsToEntity("Attack/" + type + "/PrepareTime", +this.template[type].PrepareTime || 0, this.entity),
+ "repeat": this.GetRepeatTime(type)
+ };
};
Attack.prototype.GetSplashData = function(type)
Index: binaries/data/mods/public/simulation/components/interfaces/Attack.js
===================================================================
--- binaries/data/mods/public/simulation/components/interfaces/Attack.js
+++ binaries/data/mods/public/simulation/components/interfaces/Attack.js
@@ -1,5 +1,3 @@
-Engine.RegisterInterface("Attack");
-
/**
* Message of the form { "attacker": number, "target": number, "type": string, "damage": number, "attackerOwner": number }
* sent from Attack component and by Damage component to the target entity, each time the target is attacked or damaged.
Index: binaries/data/mods/public/simulation/components/tests/test_Attack.js
===================================================================
--- binaries/data/mods/public/simulation/components/tests/test_Attack.js
+++ binaries/data/mods/public/simulation/components/tests/test_Attack.js
@@ -180,11 +180,16 @@
"repeat": 500
});
+
+ TS_ASSERT_UNEVAL_EQUALS(cmpAttack.GetRepeatTime("Ranged"), 500);
+
TS_ASSERT_UNEVAL_EQUALS(cmpAttack.GetTimers("Capture"), {
"prepare": 0,
"repeat": 1000
});
+ TS_ASSERT_UNEVAL_EQUALS(cmpAttack.GetRepeatTime("Capture"), 1000);
+
TS_ASSERT_UNEVAL_EQUALS(cmpAttack.GetSplashData("Ranged"), {
"attackData": {
"Damage": {
Index: source/simulation2/TypeList.h
===================================================================
--- source/simulation2/TypeList.h
+++ source/simulation2/TypeList.h
@@ -79,6 +79,9 @@
INTERFACE(AIManager)
COMPONENT(AIManager)
+INTERFACE(Attack)
+COMPONENT(AttackScripted)
+
INTERFACE(CinemaManager)
COMPONENT(CinemaManager)
Index: source/simulation2/components/ICmpAttack.h
===================================================================
--- /dev/null
+++ source/simulation2/components/ICmpAttack.h
@@ -0,0 +1,30 @@
+/* Copyright (C) 2020 Wildfire Games.
+ * This file is part of 0 A.D.
+ *
+ * 0 A.D. is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 0 A.D. is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with 0 A.D. If not, see .
+ */
+
+#ifndef INCLUDED_ICMPATTACK
+#define INCLUDED_ICMPATTACK
+
+#include "simulation2/system/Interface.h"
+
+class ICmpAttack : public IComponent
+{
+public:
+ virtual float GetRepeatTime(const std::string& type) const = 0;
+ DECLARE_INTERFACE_TYPE(Attack)
+};
+
+#endif // INCLUDED_ICMPATTACK
Index: source/simulation2/components/ICmpAttack.cpp
===================================================================
--- /dev/null
+++ source/simulation2/components/ICmpAttack.cpp
@@ -0,0 +1,40 @@
+/* Copyright (C) 2020 Wildfire Games.
+ * This file is part of 0 A.D.
+ *
+ * 0 A.D. is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 0 A.D. is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with 0 A.D. If not, see .
+ */
+
+#include "precompiled.h"
+
+#include "ICmpAttack.h"
+
+#include "simulation2/system/InterfaceScripted.h"
+#include "simulation2/scripting/ScriptComponent.h"
+
+
+BEGIN_INTERFACE_WRAPPER(Attack)
+END_INTERFACE_WRAPPER(Attack)
+
+class CCmpAttackScripted : public ICmpAttack
+{
+public:
+ DEFAULT_SCRIPT_WRAPPER(AttackScripted)
+
+ virtual float GetRepeatTime(const std::string& type) const
+ {
+ return m_Script.Call("GetRepeatTime", type);
+ }
+};
+
+REGISTER_COMPONENT_SCRIPT_WRAPPER(AttackScripted)
Index: source/tools/atlas/GameInterface/ActorViewer.h
===================================================================
--- source/tools/atlas/GameInterface/ActorViewer.h
+++ source/tools/atlas/GameInterface/ActorViewer.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2019 Wildfire Games.
+/* Copyright (C) 2020 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -52,6 +52,7 @@
private:
ActorViewerImpl& m;
+ float GetRepeatTimeByAttackType(const std::string& type) const;
};
#endif // INCLUDED_ACTORVIEWER
Index: source/tools/atlas/GameInterface/ActorViewer.cpp
===================================================================
--- source/tools/atlas/GameInterface/ActorViewer.cpp
+++ source/tools/atlas/GameInterface/ActorViewer.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2019 Wildfire Games.
+/* Copyright (C) 2020 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -48,6 +48,7 @@
#include "renderer/WaterManager.h"
#include "scriptinterface/ScriptInterface.h"
#include "simulation2/Simulation2.h"
+#include "simulation2/components/ICmpAttack.h"
#include "simulation2/components/ICmpOwnership.h"
#include "simulation2/components/ICmpPosition.h"
#include "simulation2/components/ICmpRangeManager.h"
@@ -377,19 +378,19 @@
if (needsAnimReload)
{
+ // Emulate the typical simulation animation behaviour.
CStr anim = animation.LowerCase();
-
- // Emulate the typical simulation animation behaviour
- float speed;
- float repeattime = 0.f;
+ float speed = 1.0f;
+ // Speed will be ignored if we have a repeat time.
+ float repeattime = 0.0f;
+ m.CurrentSpeed = 0.0f;
if (anim == "walk")
{
CmpPtr cmpUnitMotion(m.Simulation2, m.Entity);
if (cmpUnitMotion)
- speed = cmpUnitMotion->GetWalkSpeed().ToFloat();
+ speed = cmpUnitMotion->GetWalkSpeed().ToFloat();
else
- speed = 7.f; // typical unit speed
-
+ speed = 7.f; // Typical unit walk speed.
m.CurrentSpeed = speed;
}
else if (anim == "run")
@@ -398,33 +399,18 @@
if (cmpUnitMotion)
speed = cmpUnitMotion->GetWalkSpeed().ToFloat() * cmpUnitMotion->GetRunMultiplier().ToFloat();
else
- speed = 12.f; // typical unit speed
+ speed = 12.f; // Typical unit run speed.
m.CurrentSpeed = speed;
}
- else if (anim == "melee")
- {
- speed = 1.f; // speed will be ignored if we have a repeattime
- m.CurrentSpeed = 0.f;
-
- CStr code = "var cmp = Engine.QueryInterface("+CStr::FromUInt(m.Entity)+", IID_Attack); " +
- "if (cmp) cmp.GetTimers(cmp.GetBestAttack()).repeat; else 0;";
- m.Simulation2.GetScriptInterface().Eval(code.c_str(), repeattime);
- }
- else
- {
- // Play the animation at normal speed, but movement speed is zero
- speed = 1.f;
- m.CurrentSpeed = 0.f;
- }
-
- CStr sound;
- if (anim == "melee")
- sound = "attack";
- else if (anim == "build")
- sound = "build";
- else if (anim.Find("gather_") == 0)
- sound = anim;
+ else if (anim == "attack_melee")
+ repeattime = GetRepeatTimeByAttackType("Melee");
+ else if (anim == "attack_ranged")
+ repeattime = GetRepeatTimeByAttackType("Ranged");
+ else if (anim == "attack_slaughter")
+ repeattime = GetRepeatTimeByAttackType("Slaughter");
+ else if (anim == "attack_capture")
+ repeattime = GetRepeatTimeByAttackType("Capture");
CmpPtr cmpVisual(m.Simulation2, m.Entity);
if (cmpVisual)
@@ -496,6 +482,15 @@
g_ProfileViewer.ShowTable("");
}
+float ActorViewer::GetRepeatTimeByAttackType(const std::string& type) const
+{
+ CmpPtr cmpAttack(m.Simulation2, m.Entity);
+ if (cmpAttack)
+ return cmpAttack->GetRepeatTime(type);
+
+ return 0.0f;
+}
+
void ActorViewer::Render()
{
m.Terrain.MakeDirty(RENDERDATA_UPDATE_COLOR);