Skip to content

Commit

Permalink
Added reward for damaging entities (#537)
Browse files Browse the repository at this point in the history
  • Loading branch information
DaveyBiggers committed Jun 2, 2017
1 parent 959ac32 commit bb4c156
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 2 deletions.
1 change: 1 addition & 0 deletions Malmo/samples/Python_examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ set( SOURCES
discrete_3d_test.py
drawing_test.py
file_test.py
hit_test.py
human_action.py
manual_input_test.py
MazeRunner.py
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package com.microsoft.Malmo.MissionHandlers;

import java.util.HashMap;
import java.util.Map;

import net.minecraft.client.Minecraft;
import net.minecraft.util.DamageSource;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.living.LivingAttackEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;

import com.microsoft.Malmo.MissionHandlerInterfaces.IRewardProducer;
import com.microsoft.Malmo.Schemas.EntityTypes;
import com.microsoft.Malmo.Schemas.MissionInit;
import com.microsoft.Malmo.Schemas.MobWithReward;
import com.microsoft.Malmo.Schemas.RewardForDamagingEntity;

public class RewardForDamagingEntityImplementation extends RewardBase implements IRewardProducer
{
RewardForDamagingEntity params;
Map<MobWithReward, Float> damages = new HashMap<MobWithReward, Float>();

@Override
public boolean parseParameters(Object params)
{
super.parseParameters(params);
if (params == null || !(params instanceof RewardForDamagingEntity))
return false;

this.params = (RewardForDamagingEntity) params;
return true;
}

@Override
public void getReward(MissionInit missionInit, MultidimensionalReward reward)
{
super.getReward(missionInit, reward);
if (missionInit == null || Minecraft.getMinecraft().thePlayer == null)
return;
synchronized (this.damages)
{
for (MobWithReward mob : this.damages.keySet())
{
float damage_amount = this.damages.get(mob);
float damage_reward = damage_amount * mob.getReward().floatValue();
float adjusted_reward = adjustAndDistributeReward(damage_reward, this.params.getDimension(), mob.getDistribution());
reward.add(this.params.getDimension(), adjusted_reward);
}
this.damages.clear();
}
}

@Override
public void prepare(MissionInit missionInit)
{
super.prepare(missionInit);
MinecraftForge.EVENT_BUS.register(this);
}

@Override
public void cleanup()
{
super.cleanup();
MinecraftForge.EVENT_BUS.unregister(this);
}

@SubscribeEvent
public void onLivingAttackEvent(LivingAttackEvent event)
{
if (event.entity == null || event.source.getEntity() != Minecraft.getMinecraft().thePlayer)
return;
synchronized (this.damages)
{
for (MobWithReward mob : this.params.getMob())
{
// Have we caught one of these mobs?
for (EntityTypes et : mob.getType())
{
String mobName = et.value();
if (event.entity.getName().equals(mobName))
{
if (this.damages.containsKey(mob))
this.damages.put(mob, this.damages.get(mob) + event.ammount);
else
this.damages.put(mob, event.ammount);
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import java.util.ArrayList;
import java.util.HashMap;

import com.microsoft.Malmo.MissionHandlerInterfaces.ICommandHandler;
import com.microsoft.Malmo.MissionHandlerInterfaces.IRewardProducer;
import com.microsoft.Malmo.Schemas.MissionInit;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ public static void buildAchievementStats(JsonObject json, EntityPlayerMP player)
json.addProperty("MobsKilled", sfw.readStat((StatBase)StatList.mobKillsStat));
json.addProperty("PlayersKilled", sfw.readStat((StatBase)StatList.playerKillsStat));
json.addProperty("DamageTaken", sfw.readStat((StatBase)StatList.damageTakenStat));
json.addProperty("DamageDealt", sfw.readStat((StatBase)StatList.damageDealtStat));

/* Other potential reinforcement signals that may be worth researching:
json.addProperty("BlocksDestroyed", sfw.readStat((StatBase)StatList.objectBreakStats) - but objectBreakStats is an array of 32000 StatBase objects - indexed by block type.);
Expand Down
1 change: 1 addition & 0 deletions Schemas/Mission.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@
<xs:element ref="RewardForStructureCopying" minOccurs="0"/>
<xs:element ref="RewardForTimeTaken" minOccurs="0"/>
<xs:element ref="RewardForCatchingMob" minOccurs="0"/>
<xs:element ref="RewardForDamagingEntity" minOccurs="0"/>

<xs:element ref="ContinuousMovementCommands" minOccurs="0"/>
<xs:element ref="AbsoluteMovementCommands" minOccurs="0"/>
Expand Down
22 changes: 21 additions & 1 deletion Schemas/MissionHandlers.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -1469,7 +1469,7 @@
<xs:documentation>
When present, the Mod will return several observations:

* Achievement statistics: {{{DistanceTravelled}}}, {{{TimeAlive}}}, {{{MobsKilled}}}, {{{PlayersKilled}}}, {{{DamageTaken}}}
* Achievement statistics: {{{DistanceTravelled}}}, {{{TimeAlive}}}, {{{MobsKilled}}}, {{{PlayersKilled}}}, {{{DamageTaken}}}, {{{DamageDealt}}}
* Life statistics: {{{Life}}}, {{{Score}}}, {{{Food}}}, {{{Air}}}, {{{XP}}}, {{{IsAlive}}}, {{{Name}}}
* Position statistics: {{{XPos}}}, {{{YPos}}}, {{{ZPos}}}, {{{Pitch}}}, {{{Yaw}}}
* Environment statistics: {{{WorldTime}}} - current time in ticks, {{{TotalTime}}} - total world time, unaffected by ServerInitialConditions
Expand Down Expand Up @@ -1663,6 +1663,26 @@
</xs:complexContent>
</xs:complexType>

<xs:complexType name="MobWithReward">
<xs:attribute name="type" type="MobList" use="required"/>
<xs:attribute name="reward" type="xs:decimal" use="required" />
<xs:attribute name="distribution" type="xs:string" use="optional" default="" />
</xs:complexType>

<xs:element name="RewardForDamagingEntity">
<xs:annotation>
<xs:documentation>
Sends a reward when an entity is damaged.
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:choice minOccurs="1" maxOccurs="unbounded">
<xs:element name="Mob" type="MobWithReward"/>
</xs:choice>
<xs:attributeGroup ref="RewardProducerAttributes"/>
</xs:complexType>
</xs:element>

<xs:element name="RewardForReachingPosition">
<xs:annotation>
<xs:documentation>
Expand Down
1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ New: Added socket logging code to Mod, available in Mod UI.
New: Added logging code to platform, available through Malmo API.
New: startMission now provides more error details in exceptions; multi-agent samples hardened by using this.
New: ObservationFromNearbyEntities now returns entity life.
New: RewardForDamagingEntity plus sample. (#537)

0.21.0
-------------------
Expand Down

0 comments on commit bb4c156

Please sign in to comment.