← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~widelands-dev/widelands/bug-1530370-soldiers-lua into lp:widelands

 

GunChleoc has proposed merging lp:~widelands-dev/widelands/bug-1530370-soldiers-lua into lp:widelands.

Commit message:
The soldier values in the warfare tutorial are now calculated from the actual values. Added soldier values to worker help.

Requested reviews:
  Widelands Developers (widelands-dev)
Related bugs:
  Bug #1530370 in widelands: "wrong text for the healing of garrisoned soldiers"
  https://bugs.launchpad.net/widelands/+bug/1530370

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/bug-1530370-soldiers-lua/+merge/290800

See commit message.
-- 
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/bug-1530370-soldiers-lua into lp:widelands.
=== modified file 'data/campaigns/tutorial02_warfare.wmf/scripting/texts.lua'
--- data/campaigns/tutorial02_warfare.wmf/scripting/texts.lua	2016-02-17 22:13:21 +0000
+++ data/campaigns/tutorial02_warfare.wmf/scripting/texts.lua	2016-04-02 16:40:22 +0000
@@ -9,6 +9,10 @@
 include "scripting/formatting.lua"
 include "scripting/format_scenario.lua"
 
+-- We want the soldier here so we can get some actual stats.
+local tribe = wl.Game():get_tribe_description("barbarians")
+local soldier = wl.Game():get_worker_description(tribe.soldier)
+
 -- =============
 -- Texts below
 -- =============
@@ -29,17 +33,24 @@
    body = rt(
       p(_[[A new soldier is created like a worker: when a military building needs a soldier, a carrier grabs the needed weapons and armor from a warehouse (or your headquarters) and walks up the road to your new building. Basic Barbarian soldiers do not use armor, they only need an ax.]]) ..
       p(_[[Take a look at the soldiers that are on their way to our military buildings. They look different from normal workers: they have a health bar over their head that displays their remaining health, and they have four symbols, which symbolize the individual soldier’s current levels in the four different categories: health, attack, defense and evade.]]) ..
-      p(_[[If a Barbarian soldier is fully trained, he has level 3 health, level 5 attack, level 0 defense and level 2 evade. This is one fearsome warrior then! The individual abilities have the following meaning:]])
+      -- TRANSLATORS: the current stats are: 3 health, 5 attack, 0 defense, 2 evade.
+      p((_[[If a Barbarian soldier is fully trained, he has level %1% health, level %2% attack, level %3% defense and level %4% evade. This is one fearsome warrior then! The individual abilities have the following meaning:]]):bformat(soldier.max_health_level, soldier.max_attack_level, soldier.max_defense_level, soldier.max_evade_level))
    ) ..
-   rt("image=tribes/workers/barbarians/soldier/health_level0.png", h2(_"Health:"))..
-   rt(p(_[[The total life of a soldier. A Barbarian soldier starts with 130 health, and he will gain 28 health with each health level.]])) ..
+   rt("image=tribes/workers/barbarians/soldier/health_level0.png", h2(_"Health:")) ..
+   -- TRANSLATORS: the current stats are: 13000 health, 2800 health gain.
+   rt(p((_[[The total life of a soldier. A Barbarian soldier starts with %1% health, and he will gain %2% health with each health level.]]):bformat(soldier.base_health, soldier.health_incr_per_level))) ..
    rt("image=tribes/workers/barbarians/soldier/attack_level0.png", h2(_"Attack:")) ..
-   rt(p(_[[The amount of damage a soldier will inflict on the enemy when an attack is successful. A Barbarian soldier with attack level 0 inflicts ~14 points of health damage when he succeeds in hitting an enemy. For each attack level, he gains 7 damage points.]])) ..
+   -- TRANSLATORS: the current stats are: 1400 damage, gains 850 damage points.
+   rt(p(_[[The amount of damage a soldier will inflict on the enemy when an attack is successful. A Barbarian soldier with attack level 0 inflicts ~%1% points of health damage when he succeeds in hitting an enemy. For each attack level, he gains %2% damage points.]]):bformat(soldier.base_min_attack + (soldier.base_max_attack - soldier.base_min_attack) / 2, soldier.attack_incr_per_level)) ..
    -- The Atlanteans' image, because the Barbarian one has a white background
    rt("image=tribes/workers/atlanteans/soldier/defense_level0.png", h2(_"Defense:")) ..
-   rt(p(_[[The defense is the percentage that is subtracted from the attack value. The Barbarians cannot train in this skill and therefore have always defense level 0, which means that the damage is always reduced by 3%. If an attacker with an attack value of 35 points hits a Barbarian soldier, the Barbarian will lose 35·0.97 = 34 health.]])) ..
+   -- TRANSLATORS: the current stats are: 3%. The calculated health value is 3395
+   -- TRANSLATORS: The last two %% after the placeholder are the percent symbol.
+   rt(p(_[[The defense is the percentage that is subtracted from the attack value. The Barbarians cannot train in this skill and therefore have always defense level 0, which means that the damage is always reduced by %1%%%. If an attacker with an attack value of 3500 points hits a Barbarian soldier, the Barbarian will lose 3500·%2%%% = %3% health.]]):bformat(soldier.base_defense, (100 - soldier.base_defense), 3500 * (100 - soldier.base_defense) / 100)) ..
    rt("image=tribes/workers/barbarians/soldier/evade_level0.png", h2(_"Evade:")) ..
-   rt(p(_[[Evade is the chance that the soldier is able to dodge an attack. A level 0 Barbarian has a 25% chance to evade an attack, and this increases in steps of 15% for each level.]]))
+   -- TRANSLATORS: the current stats are: 25% evade, increases in steps of 15%.
+   -- TRANSLATORS: The last two %% after the placeholder are the percent symbol.
+   rt(p(_[[Evade is the chance that the soldier is able to dodge an attack. A level 0 Barbarian has a %1%%% chance to evade an attack, and this increases in steps of %2%%% for each level.]]):bformat(soldier.base_evade, soldier.evade_incr_per_level))
 }
 
 battlearena1 = {

=== modified file 'data/tribes/scripting/help/worker_help.lua'
--- data/tribes/scripting/help/worker_help.lua	2016-03-22 07:32:14 +0000
+++ data/tribes/scripting/help/worker_help.lua	2016-04-02 16:40:22 +0000
@@ -157,7 +157,59 @@
                worker_description.needed_experience
             )
       end
-      result = result ..  rt("text-align=right", p(exp_string))
+      result = result .. rt("text-align=right", p(exp_string))
+   end
+   -- Soldier properties
+   if (worker_description.type_name == "soldier") then
+      -- TRANSLATORS: Soldier levels
+      result = result .. rt(h2(_"Levels"))
+
+      result = result .. rt(h3(_"Health"))
+      result = result .. rt(p(
+         listitem_bullet(
+            -- TRANSLATORS: Soldier health / defense / evade points. A 5 digit number.
+            (_"Starts at %1% points."):bformat(worker_description.base_health)) ..
+         listitem_bullet(
+            -- TRANSLATORS: Soldier health / attack defense / evade points
+            ngettext("Increased by %1% point for each level.", "Increased by %1% points for each level.", worker_description.health_incr_per_level):bformat(worker_description.health_incr_per_level)) ..
+         listitem_bullet(
+            -- TRANSLATORS: Soldier health / attack defense / evade level
+            ngettext("The maximum level is %1%.", "The maximum level is %1%.", worker_description.max_health_level):bformat(worker_description.max_health_level))))
+
+      result = result .. rt(h3(_"Attack"))
+      result = result .. rt(p(
+      -- TRANSLATORS: Points are 4 digit numbers.
+         listitem_bullet(_"A random value between %1% and %2% points is added to each attack."):bformat(worker_description.base_min_attack, worker_description.base_max_attack) ..
+
+         listitem_bullet(
+            ngettext("Increased by %1% point for each level.", "Increased by %1% points for each level.", worker_description.attack_incr_per_level):bformat(worker_description.attack_incr_per_level)) ..
+         listitem_bullet(
+            ngettext("The maximum level is %1%.", "The maximum level is %1%.", worker_description.max_attack_level):bformat(worker_description.max_attack_level))))
+
+      result = result .. rt(h3(_"Defense"))
+      if (worker_description.max_defense_level > 0) then
+         result = result .. rt(p(
+            listitem_bullet(
+               (_"Starts at %d%%."):bformat(worker_description.base_defense)) ..
+            listitem_bullet(
+               (_"Increased by %d%% for each level."):bformat(worker_description.defense_incr_per_level)) ..
+            listitem_bullet(
+               ngettext("The maximum level is %1%.", "The maximum level is %1%.", worker_description.max_defense_level):bformat(worker_description.max_defense_level))))
+      else
+         result = result .. rt(p(
+            listitem_bullet(
+               (_"Starts at %d%%."):bformat(worker_description.base_defense)) ..
+            listitem_bullet(_"This solder cannot be trained in defense")))
+      end
+
+      result = result .. rt(h3(_"Evade"))
+      result = result .. rt(p(
+         listitem_bullet(
+            (_"Starts at %d%%."):bformat(worker_description.base_evade)) ..
+         listitem_bullet(
+            (_"Increased by %d%% for each level."):bformat(worker_description.evade_incr_per_level)) ..
+         listitem_bullet(
+            ngettext("The maximum level is %1%.", "The maximum level is %1%.", worker_description.max_evade_level):bformat(worker_description.max_evade_level))))
    end
    return result
 end

=== modified file 'src/scripting/lua_map.cc'
--- src/scripting/lua_map.cc	2016-03-22 07:32:14 +0000
+++ src/scripting/lua_map.cc	2016-04-02 16:40:22 +0000
@@ -606,7 +606,7 @@
 			case MapObjectType::CARRIER:
 				return CAST_TO_LUA(WorkerDescr, LuaWorkerDescription);
 			case MapObjectType::SOLDIER:
-				return CAST_TO_LUA(WorkerDescr, LuaWorkerDescription);
+				return CAST_TO_LUA(SoldierDescr, LuaSoldierDescription);
 			case MapObjectType::IMMOVABLE:
 				return CAST_TO_LUA(ImmovableDescr, LuaImmovableDescription);
 			default:
@@ -2716,19 +2716,176 @@
 
 
 
-/*
- ==========================================================
- LUA METHODS
- ==========================================================
- */
-
-
-
-/*
- ==========================================================
- C METHODS
- ==========================================================
- */
+
+/* RST
+SoldierDescription
+-----------------
+
+.. class:: SoldierDescription
+
+	A static description of a tribe's soldier, so it can be used in help files
+	without having to access an actual instance of the worker on the map.
+	See also class WorkerDescription for more properties.
+*/
+const char LuaSoldierDescription::className[] = "SoldierDescription";
+const MethodType<LuaSoldierDescription> LuaSoldierDescription::Methods[] = {
+	{nullptr, nullptr},
+};
+const PropertyType<LuaSoldierDescription> LuaSoldierDescription::Properties[] = {
+	PROP_RO(LuaSoldierDescription, max_health_level),
+	PROP_RO(LuaSoldierDescription, max_attack_level),
+	PROP_RO(LuaSoldierDescription, max_defense_level),
+	PROP_RO(LuaSoldierDescription, max_evade_level),
+	PROP_RO(LuaSoldierDescription, base_health),
+	PROP_RO(LuaSoldierDescription, base_min_attack),
+	PROP_RO(LuaSoldierDescription, base_max_attack),
+	PROP_RO(LuaSoldierDescription, base_defense),
+	PROP_RO(LuaSoldierDescription, base_evade),
+	PROP_RO(LuaSoldierDescription, health_incr_per_level),
+	PROP_RO(LuaSoldierDescription, attack_incr_per_level),
+	PROP_RO(LuaSoldierDescription, defense_incr_per_level),
+	PROP_RO(LuaSoldierDescription, evade_incr_per_level),
+	{nullptr, nullptr, nullptr},
+};
+
+
+/*
+ ==========================================================
+ PROPERTIES
+ ==========================================================
+ */
+
+
+/* RST
+	.. attribute:: get_max_health_level
+
+		(RO) The maximum health level that the soldier can have.
+*/
+int LuaSoldierDescription::get_max_health_level(lua_State * L) {
+	lua_pushinteger(L, get()->get_max_health_level());
+	return 1;
+}
+
+/* RST
+	.. attribute:: max_attack_level
+
+		(RO) The maximum attack level that the soldier can have.
+*/
+int LuaSoldierDescription::get_max_attack_level(lua_State * L) {
+	lua_pushinteger(L, get()->get_max_attack_level());
+	return 1;
+}
+
+/* RST
+	.. attribute:: max_defense_level
+
+		(RO) The maximum defense level that the soldier can have.
+*/
+int LuaSoldierDescription::get_max_defense_level(lua_State * L) {
+	lua_pushinteger(L, get()->get_max_defense_level());
+	return 1;
+}
+
+/* RST
+	.. attribute:: max_evade_level
+
+		(RO) The maximum evade level that the soldier can have.
+*/
+int LuaSoldierDescription::get_max_evade_level(lua_State * L) {
+	lua_pushinteger(L, get()->get_max_evade_level());
+	return 1;
+}
+
+/* RST
+	.. attribute:: get_base_health
+
+		(RO) The health points that the soldier starts with
+*/
+int LuaSoldierDescription::get_base_health(lua_State * L) {
+	lua_pushinteger(L, get()->get_base_health());
+	return 1;
+}
+
+
+/* RST
+	.. attribute:: base_min_attack
+
+		(RO) The attack points that the soldier starts with
+*/
+int LuaSoldierDescription::get_base_min_attack(lua_State * L) {
+	lua_pushinteger(L, get()->get_base_min_attack());
+	return 1;
+}
+
+/* RST
+	.. attribute:: base_max_attack
+
+		(RO) The maximum attack points that the soldier can get
+*/
+int LuaSoldierDescription::get_base_max_attack(lua_State * L) {
+	lua_pushinteger(L, get()->get_base_max_attack());
+	return 1;
+}
+
+/* RST
+	.. attribute:: base_defense
+
+		(RO) The defense points that the soldier starts with
+*/
+int LuaSoldierDescription::get_base_defense(lua_State * L) {
+	lua_pushinteger(L, get()->get_base_defense());
+	return 1;
+}
+
+/* RST
+	.. attribute:: base_evade
+
+		(RO) The evade points that the soldier starts with
+*/
+int LuaSoldierDescription::get_base_evade(lua_State * L) {
+	lua_pushinteger(L, get()->get_base_evade());
+	return 1;
+}
+
+/* RST
+	.. attribute:: get_health_incr_per_level
+
+		(RO) The health points that the soldier will gain with each level.
+*/
+int LuaSoldierDescription::get_health_incr_per_level(lua_State * L) {
+	lua_pushinteger(L, get()->get_health_incr_per_level());
+	return 1;
+}
+
+/* RST
+	.. attribute:: attack_incr_per_level
+
+		(RO) The attack points that the soldier will gain with each level.
+*/
+int LuaSoldierDescription::get_attack_incr_per_level(lua_State * L) {
+	lua_pushinteger(L, get()->get_attack_incr_per_level());
+	return 1;
+}
+
+/* RST
+	.. attribute:: defense_incr_per_level
+
+		(RO) The defense points that the soldier will gain with each level.
+*/
+int LuaSoldierDescription::get_defense_incr_per_level(lua_State * L) {
+	lua_pushinteger(L, get()->get_defense_incr_per_level());
+	return 1;
+}
+
+/* RST
+	.. attribute:: evade_incr_per_level
+
+		(RO) The evade points that the soldier will gain with each level.
+*/
+int LuaSoldierDescription::get_evade_incr_per_level(lua_State * L) {
+	lua_pushinteger(L, get()->get_evade_incr_per_level());
+	return 1;
+}
 
 /* RST
 ResourceDescription
@@ -3142,6 +3299,8 @@
 			return CAST_TO_LUA(ImmovableDescr, LuaImmovableDescription);
 		case (MapObjectType::WORKER):
 			return CAST_TO_LUA(WorkerDescr, LuaWorkerDescription);
+		case (MapObjectType::SOLDIER):
+			return CAST_TO_LUA(SoldierDescr, LuaSoldierDescription);
 		default:
 			return CAST_TO_LUA(MapObjectDescr, LuaMapObjectDescription);
 	}
@@ -5536,6 +5695,11 @@
 	add_parent<LuaWorkerDescription, LuaMapObjectDescription>(L);
 	lua_pop(L, 1); // Pop the meta table
 
+	register_class<LuaSoldierDescription>(L, "map", true);
+	add_parent<LuaSoldierDescription, LuaWorkerDescription>(L);
+	add_parent<LuaSoldierDescription, LuaMapObjectDescription>(L);
+	lua_pop(L, 1); // Pop the meta table
+
 	register_class<LuaResourceDescription>(L, "map");
 	register_class<LuaTerrainDescription>(L, "map");
 

=== modified file 'src/scripting/lua_map.h'
--- src/scripting/lua_map.h	2016-03-14 19:56:14 +0000
+++ src/scripting/lua_map.h	2016-04-02 16:40:22 +0000
@@ -558,6 +558,50 @@
 	CASTED_GET_DESCRIPTION(WorkerDescr)
 };
 
+
+class LuaSoldierDescription : public LuaWorkerDescription {
+public:
+	LUNA_CLASS_HEAD(LuaSoldierDescription);
+
+	virtual ~LuaSoldierDescription() {}
+
+	LuaSoldierDescription() {}
+	LuaSoldierDescription(const Widelands::SoldierDescr* const soldierdescr)
+		: LuaWorkerDescription(soldierdescr) {
+	}
+	LuaSoldierDescription(lua_State* L) : LuaWorkerDescription(L) {
+	}
+
+
+	/*
+	 * Properties
+	 */
+	int get_max_health_level(lua_State*);
+	int get_max_attack_level(lua_State*);
+	int get_max_defense_level(lua_State*);
+	int get_max_evade_level(lua_State*);
+	int get_base_health(lua_State*);
+	int get_base_min_attack(lua_State*);
+	int get_base_max_attack(lua_State*);
+	int get_base_defense(lua_State*);
+	int get_base_evade(lua_State*);
+	int get_health_incr_per_level(lua_State*);
+	int get_attack_incr_per_level(lua_State*);
+	int get_defense_incr_per_level(lua_State*);
+	int get_evade_incr_per_level(lua_State*);
+
+	/*
+	 * Lua methods
+	 */
+
+	/*
+	 * C methods
+	 */
+
+private:
+	CASTED_GET_DESCRIPTION(SoldierDescr)
+};
+
 #undef CASTED_GET_DESCRIPTION
 
 


Follow ups