Ticket #1719: AttackNotificationApr112013.diff

File AttackNotificationApr112013.diff, 22.2 KB (added by madmax, 11 years ago)

New patch with better attack code from zoot

  • binaries/data/mods/public/gui/session/messages.js

    diff --git a/binaries/data/mods/public/gui/session/messages.js b/binaries/data/mods/public/gui/session/messages.js
    index f296bcf..2440e17 100644
    a b function handleNotifications()  
    7878            "amounts": notification.amounts
    7979        });
    8080    }
     81    else if (notification.type == "attack")
     82    {
     83        if (notification.player == Engine.GetPlayerID())
     84        {
     85            Engine.GuiInterfaceCall("PlaySound", { "name":"attacked", "entity": notification.message.target });
     86        }
     87    }
    8188    else
    8289    {
    8390        // Only display notifications directed to this player
    function addChatMessage(msg, playerAssignments)  
    356363
    357364        formatted = "[color=\"" + playerColor + "\"]" + username + "[/color] has sent you " + amounts + ".";
    358365        break;
     366    case "attack":
     367        if (msg.player != Engine.GetPlayerID())
     368            return;
     369
     370        formatted = "We're under attack!";
     371        break;
    359372    case "message":
    360373        // May have been hidden by the 'team' command.
    361374        if (msg.hide)
  • binaries/data/mods/public/simulation/components/Armour.js

    diff --git a/binaries/data/mods/public/simulation/components/Armour.js b/binaries/data/mods/public/simulation/components/Armour.js
    index eef945e..f5457ea 100644
    a b Armour.prototype.SetInvulnerability = function(invulnerability)  
    4242    this.invulnerable = invulnerability;
    4343};
    4444
    45 Armour.prototype.TakeDamage = function(hack, pierce, crush)
     45Armour.prototype.TakeDamage = function(hack, pierce, crush, source)
    4646{
    4747    if (this.invulnerable)
    4848        return { "killed": false };
    Armour.prototype.TakeDamage = function(hack, pierce, crush)  
    5757    //  Round to nearest integer, since HP is integral
    5858    var total = Math.max(1, Math.round(adjHack + adjPierce + adjCrush));
    5959
     60    // Alert target owner of attack
     61    var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
     62    var cmpAttackDetection = QueryPlayerIDInterface(cmpOwnership.GetOwner(), IID_AttackDetection);
     63    var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
     64    var now = cmpTimer.GetTime();
     65    if (!(this.lastAttack > now - cmpAttackDetection.GetSuppressionTime()))
     66        cmpAttackDetection.AttackAlert(this.entity, source);
     67    this.lastAttack = now;
     68
    6069    // Reduce health
    6170    var cmpHealth = Engine.QueryInterface(this.entity, IID_Health);
    6271    return cmpHealth.Reduce(total);
  • binaries/data/mods/public/simulation/components/Attack.js

    diff --git a/binaries/data/mods/public/simulation/components/Attack.js b/binaries/data/mods/public/simulation/components/Attack.js
    index 0a9a707..469a582 100644
    a b Attack.prototype.CauseDamage = function(data)  
    691691    var cmpDamageReceiver = Engine.QueryInterface(data.target, IID_DamageReceiver);
    692692    if (!cmpDamageReceiver)
    693693        return;
    694     var targetState = cmpDamageReceiver.TakeDamage(strengths.hack * damageMultiplier, strengths.pierce * damageMultiplier, strengths.crush * damageMultiplier);
     694    var targetState = cmpDamageReceiver.TakeDamage(strengths.hack * damageMultiplier, strengths.pierce * damageMultiplier, strengths.crush * damageMultiplier, this.entity);
    695695    // if target killed pick up loot and credit experience
    696696    if (targetState.killed == true)
    697697    {
  • new file inaries/data/mods/public/simulation/components/AttackDetection.js

    diff --git a/binaries/data/mods/public/simulation/components/AttackDetection.js b/binaries/data/mods/public/simulation/components/AttackDetection.js
    new file mode 100644
    index 0000000..98448b8
    - +  
     1function AttackDetection() {}
     2
     3AttackDetection.prototype.Schema =
     4    "<a:help>Detects incoming attacks.</a:help>" +
     5    "<a:example/>" +
     6    "<a:component type='system'/>" +
     7    "<empty/>";
     8
     9AttackDetection.prototype.Init = function()
     10{
     11    this.suppressionTransferRange = 50; // Any attacks within this range will replace the previous attack suppression.
     12    this.suppressionRange = 150; // Other attacks within this distance will not be registered.
     13    this.suppressionTime = 40 * 1000; // Other attacks within this time will not be registered.
     14
     15    this.suppressedList = [];
     16};
     17
     18// Utility function for calculating the distance between two attack events.
     19AttackDetection.prototype.distance = function(pos1, pos2)
     20{
     21    var xs = pos2.x - pos1.x;
     22    var zs = pos2.z - pos1.z;
     23    return Math.sqrt(Math.pow(xs, 2) + Math.pow(zs, 2));
     24}
     25
     26AttackDetection.prototype.addSuppression = function(event)
     27{
     28    this.suppressedList.push(event);
     29
     30    var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
     31    cmpTimer.SetTimeout(this.entity, IID_AttackDetection, "HandleTimeout", this.suppressionTime);
     32}
     33
     34AttackDetection.prototype.handleAttack = function(target, attacker)
     35{
     36    var cmpPlayer = Engine.QueryInterface(this.entity, IID_Player);
     37    var cmpOwnership = Engine.QueryInterface(target, IID_Ownership);
     38    // Don't register attacks dealt against others.
     39    if (cmpPlayer.GetPlayerID() != cmpOwnership.GetOwner())
     40        return;
     41
     42    var cmpPosition = Engine.QueryInterface(target, IID_Position);
     43    if (!cmpPosition || !cmpPosition.IsInWorld())
     44        return;
     45    var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
     46    var event = {target: target, position: cmpPosition.GetPosition(), time: cmpTimer.GetTime()};
     47
     48    for (var i = 0; i < this.suppressedList.length; i++)
     49    {
     50        var element = this.suppressedList[i];
     51       
     52        // If the new attack is within suppression distance of this element then check if the element should be updated
     53        // and then return.
     54        var dist = this.distance(element.position, event.position);
     55        if (dist < this.suppressionRange)
     56        {
     57            if (dist < this.suppressionTransferRange)
     58                element = event;
     59            return;
     60        }
     61    }
     62   
     63    this.addSuppression(event);
     64    Engine.PostMessage(this.entity, MT_AttackDetected, { "player": cmpPlayer.GetPlayerID(), "event": event });
     65    var cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
     66    cmpGuiInterface.PushNotification({"type": "attack", "player": cmpPlayer.GetPlayerID(), "message": event});
     67};
     68
     69//// Message handlers ////
     70
     71AttackDetection.prototype.OnGlobalAttacked = function(msg)
     72{
     73    var cmpPlayer = Engine.QueryInterface(this.entity, IID_Player);
     74    var cmpOwnership = Engine.QueryInterface(msg.target, IID_Ownership);
     75    if (cmpOwnership.GetOwner() == cmpPlayer.GetPlayerID())
     76        Engine.PostMessage(msg.target, MT_PingOwner);
     77};
     78
     79//// External interface ////
     80
     81AttackDetection.prototype.AttackAlert = function(target, attacker)
     82{
     83    this.handleAttack(target, attacker);
     84};
     85
     86AttackDetection.prototype.GetSuppressionTime = function()
     87{
     88    return this.suppressionTime;
     89};
     90
     91AttackDetection.prototype.HandleTimeout = function()
     92{
     93    var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
     94    for (var i = 0; i < this.suppressedList.length; i++)
     95    {
     96        var event = this.suppressedList[i];
     97       
     98        // Check if this event has timed out.
     99        if (cmpTimer.GetTime() - event.time >= this.suppressionTime)
     100        {
     101            this.suppressedList.splice(i, 1);
     102            i--;
     103            return;
     104        }
     105    }
     106};
     107
     108AttackDetection.prototype.GetIncomingAttacks = function()
     109{
     110    return this.suppressedList;
     111};
     112
     113Engine.RegisterComponentType(IID_AttackDetection, "AttackDetection", AttackDetection);
  • binaries/data/mods/public/simulation/components/GuiInterface.js

    diff --git a/binaries/data/mods/public/simulation/components/GuiInterface.js b/binaries/data/mods/public/simulation/components/GuiInterface.js
    index a5418be..da8dc99 100644
    a b GuiInterface.prototype.GetBattleState = function(player)  
    620620    return cmpBattleDetection.GetState();
    621621};
    622622
     623// Returns a list of ongoing attacks against the player.
     624GuiInterface.prototype.GetIncomingAttacks = function(player)
     625{
     626    var cmpAttackDetection = QueryPlayerIDInterface(player, IID_AttackDetection);
     627    return cmpAttackDetection.GetIncomingAttacks();
     628};
     629
    623630// Used to show a red square over GUI elements you can't yet afford.
    624631GuiInterface.prototype.GetNeededResources = function(player, amounts)
    625632{
    var exposedFunctions = {  
    17201727    "CheckTechnologyRequirements": 1,
    17211728    "GetStartedResearch": 1,
    17221729    "GetBattleState": 1,
     1730    "GetIncomingAttacks": 1,
    17231731    "GetNeededResources": 1,
    17241732    "GetNextNotification": 1,
    17251733
  • new file inaries/data/mods/public/simulation/components/interfaces/AttackDetection.js

    diff --git a/binaries/data/mods/public/simulation/components/interfaces/AttackDetection.js b/binaries/data/mods/public/simulation/components/interfaces/AttackDetection.js
    new file mode 100644
    index 0000000..d168646
    - +  
     1Engine.RegisterInterface("AttackDetection");
     2
     3// Message of the form { "event": { "target": 123, "position": { "x": 123, "z": 456 }, "time": 1 }.
     4// sent when an entity is attacked.
     5//Engine.RegisterMessageType("EntityAttacked");
     6
     7// Message of the form { "player": 1, "event": { "target": 123 , "position": { "x": 123, "z": 456 }, "time": 1, }.
     8// sent when a new attack is detected.
     9Engine.RegisterMessageType("AttackDetected");
  • binaries/data/mods/public/simulation/templates/special/player.xml

    diff --git a/binaries/data/mods/public/simulation/templates/special/player.xml b/binaries/data/mods/public/simulation/templates/special/player.xml
    index eaa28e6..97ff335 100644
    a b  
    1212  <Player/>
    1313  <StatisticsTracker/>
    1414  <TechnologyManager/>
     15  <AttackDetection/>
    1516  <BattleDetection>
    1617    <TimerInterval>200</TimerInterval>
    1718    <RecordLength>12</RecordLength>
  • binaries/data/mods/public/simulation/templates/template_structure.xml

    diff --git a/binaries/data/mods/public/simulation/templates/template_structure.xml b/binaries/data/mods/public/simulation/templates/template_structure.xml
    index bfe0e5e..f20fdfc 100644
    a b  
    8585      <select>interface/select/building/sel_universal.xml</select>
    8686      <constructed>interface/complete/building/complete_universal.xml</constructed>
    8787      <death>attack/destruction/building_collapse_large.xml</death>
     88      <attacked>interface/alarm/alarm_attackplayer.xml</attacked>   
    8889    </SoundGroups>
    8990  </Sound>
    9091  <StatusBars>
  • binaries/data/mods/public/simulation/templates/template_unit_cavalry.xml

    diff --git a/binaries/data/mods/public/simulation/templates/template_unit_cavalry.xml b/binaries/data/mods/public/simulation/templates/template_unit_cavalry.xml
    index 420836e..a16aa0c 100644
    a b  
    7979      <walk>actor/mounted/movement/walk.xml</walk>
    8080      <run>actor/mounted/movement/walk.xml</run>
    8181      <attack>attack/weapon/sword.xml</attack>
     82      <attacked>interface/alarm/alarm_attackplayer.xml</attacked>
    8283      <death>actor/fauna/death/death_horse.xml</death>
    8384      <trained>interface/alarm/alarm_create_cav.xml</trained>
    8485    </SoundGroups>
  • binaries/data/mods/public/simulation/templates/template_unit_champion.xml

    diff --git a/binaries/data/mods/public/simulation/templates/template_unit_champion.xml b/binaries/data/mods/public/simulation/templates/template_unit_champion.xml
    index 11b332e..16f5745 100644
    a b  
    1414    <stone>0</stone>
    1515    <metal>20</metal>
    1616  </Loot>
     17  <Sound>
     18    <SoundGroups>
     19      <attacked>interface/alarm/alarm_attackplayer.xml</attacked>
     20    </SoundGroups>
     21  </Sound>
    1722</Entity>
  • binaries/data/mods/public/simulation/templates/template_unit_hero.xml

    diff --git a/binaries/data/mods/public/simulation/templates/template_unit_hero.xml b/binaries/data/mods/public/simulation/templates/template_unit_hero.xml
    index b36b629..9e8daaa 100644
    a b  
    6060  <Sound>
    6161    <SoundGroups>
    6262      <attack>attack/weapon/sword.xml</attack>
     63      <attacked>interface/alarm/alarm_attackplayer.xml</attacked>
    6364      <death>actor/human/death/death.xml</death>
    6465    </SoundGroups>
    6566  </Sound>
  • binaries/data/mods/public/simulation/templates/template_unit_infantry.xml

    diff --git a/binaries/data/mods/public/simulation/templates/template_unit_infantry.xml b/binaries/data/mods/public/simulation/templates/template_unit_infantry.xml
    index 427a03a..fe16b3b 100644
    a b  
    9292  <Sound>
    9393    <SoundGroups>
    9494      <select>voice/hellenes/civ/civ_male_select.xml</select>
     95      <attacked>interface/alarm/alarm_attackplayer.xml</attacked>
    9596      <order_walk>voice/hellenes/civ/civ_male_ack.xml</order_walk>
    9697      <order_attack>voice/hellenes/civ/civ_male_attack.xml</order_attack>
    9798      <order_gather>voice/hellenes/civ/civ_male_ack.xml</order_gather>
  • binaries/data/mods/public/simulation/templates/template_unit_mechanical.xml

    diff --git a/binaries/data/mods/public/simulation/templates/template_unit_mechanical.xml b/binaries/data/mods/public/simulation/templates/template_unit_mechanical.xml
    index 3a73cc7..67d63bd 100644
    a b  
    2121    <stone>0</stone>
    2222    <metal>25</metal>
    2323  </Loot>
     24  <Sound>
     25    <SoundGroups>
     26      <attacked>interface/alarm/alarm_attackplayer.xml</attacked>
     27    </SoundGroups>
     28  </Sound>
    2429</Entity>
  • binaries/data/mods/public/simulation/templates/template_unit_support.xml

    diff --git a/binaries/data/mods/public/simulation/templates/template_unit_support.xml b/binaries/data/mods/public/simulation/templates/template_unit_support.xml
    index 7c37c1a..a327fac 100644
    a b  
    2323  <Sound>
    2424    <SoundGroups>
    2525      <trained>interface/alarm/alarm_create_worker.xml</trained>
     26      <attacked>interface/alarm/alarm_attackplayer.xml</attacked>
    2627    </SoundGroups>
    2728  </Sound>
    2829  <UnitAI>
  • source/gui/MiniMap.cpp

    diff --git a/source/gui/MiniMap.cpp b/source/gui/MiniMap.cpp
    index ad1b7f9..793578b 100644
    a b  
    1 /* Copyright (C) 2012 Wildfire Games.
     1/* Copyright (C) 2013 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
    44 * 0 A.D. is free software: you can redistribute it and/or modify
    static unsigned int ScaleColor(unsigned int color, float x)  
    6969        m_ShallowPassageHeight = pathingSettings.GetChild("default").GetChild("MaxWaterDepth").ToFloat();
    7070    else
    7171        m_ShallowPassageHeight = 0.0f;
     72
     73    m_ChangePingColor = 0;
    7274}
    7375
    7476CMiniMap::~CMiniMap()
    void CMiniMap::Draw()  
    469471                v.a = 255;
    470472                v.x = posX.ToFloat()*sx;
    471473                v.y = -posZ.ToFloat()*sy;
     474
     475                // Check minimap pinging to indicate something
     476                if (cmpMinimap->IsEntityPinging()) {
     477
     478                    // Override the normal rendering of the entity with the ping color
     479                    // Note: If the pinged entity's dot is rendered over by another entity's
     480                    // dot then it will be invisible & the ping will be not be seen.
     481                    // We can try to move the pinged dots towards the end in the vertexArray
     482                    // Keep 2 pointers and insert pinged dots at end, unpinged at current position
     483                    if (m_ChangePingColor > PING_DURATION/2) {
     484                        v.r = 255; // bright red
     485                        v.g = 1;
     486                        v.b = 1;
     487                    }
     488
     489                    // Must reduce ping count every frame
     490                    u32 pingCount = cmpMinimap->GetRemainingPingCount();
     491                    if (pingCount <= 0) {
     492                        // Also turns off ping flag if 0 passed in
     493                        cmpMinimap->SetRemainingPingCount(0);
     494                    }
     495                    else {
     496                        cmpMinimap->SetRemainingPingCount(pingCount - 1);
     497                    }
     498                }
     499
    472500                vertexArray.push_back(v);
    473501            }
    474502        }
    475503    }
    476504
     505    // Cycle the ping color counter as needed
     506    m_ChangePingColor = (m_ChangePingColor + 1) > PING_DURATION ? 0 : (m_ChangePingColor + 1);
     507
    477508    if (!vertexArray.empty())
    478509    {
    479510        glEnableClientState(GL_VERTEX_ARRAY);
    void CMiniMap::Draw()  
    497528    }
    498529
    499530    PROFILE_END("minimap units");
    500    
     531
    501532    if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER)
    502533    {
    503534        tech->EndPass();
  • source/gui/MiniMap.h

    diff --git a/source/gui/MiniMap.h b/source/gui/MiniMap.h
    index 4fbc34a..5c6c7a2 100644
    a b  
    1 /* Copyright (C) 2012 Wildfire Games.
     1/* Copyright (C) 2013 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
    44 * 0 A.D. is free software: you can redistribute it and/or modify
     
    1818#ifndef INCLUDED_MINIMAP
    1919#define INCLUDED_MINIMAP
    2020
     21// GUI
    2122#include "gui/GUI.h"
    2223
     24// Types
     25#include "lib/types.h"
     26
    2327class CCamera;
    2428class CTerrain;
    2529
     30// Pinging constants - Controls blink duration of the ping, smaller means higher
     31// ping frequency
     32const unsigned int PING_DURATION = 50;
     33
    2634class CMiniMap : public IGUIObject
    2735{
    2836    GUI_OBJECT(CMiniMap)
    2937public:
    3038    CMiniMap();
    3139    virtual ~CMiniMap();
     40
    3241protected:
    3342    virtual void Draw();
    3443
    class CMiniMap : public IGUIObject  
    8190    // maximal water height to allow the passage of a unit (for underwater shallows).
    8291    float m_ShallowPassageHeight;
    8392
     93    // For tracking the ping color
     94    u32 m_ChangePingColor;
     95
    8496    void DrawTexture(float coordMax, float angle, float x, float y, float x2, float y2, float z);
    8597
    8698    void DrawViewRect();
  • source/simulation2/MessageTypes.h

    diff --git a/source/simulation2/MessageTypes.h b/source/simulation2/MessageTypes.h
    index de8a31b..9ca5f9b 100644
    a b class CMessageVisionRangeChanged : public CMessage  
    398398    entity_pos_t newRange;
    399399};
    400400
     401/**
     402 * Sent when an entity is pinged
     403 */
     404class CMessagePingOwner : public CMessage
     405{
     406public:
     407    DEFAULT_MESSAGE_IMPL(PingOwner)
     408
     409    CMessagePingOwner()
     410    {
     411    }
     412};
     413
    401414#endif // INCLUDED_MESSAGETYPES
  • source/simulation2/TypeList.h

    diff --git a/source/simulation2/TypeList.h b/source/simulation2/TypeList.h
    index f14848c..663f3e7 100644
    a b  
    4949MESSAGE(PathResult)
    5050MESSAGE(TechnologyModification)
    5151MESSAGE(VisionRangeChanged)
     52MESSAGE(PingOwner)
    5253
    5354// TemplateManager must come before all other (non-test) components,
    5455// so that it is the first to be (de)serialized
  • source/simulation2/components/CCmpMinimap.cpp

    diff --git a/source/simulation2/components/CCmpMinimap.cpp b/source/simulation2/components/CCmpMinimap.cpp
    index ac8004d..fb3daf9 100644
    a b  
    1 /* Copyright (C) 2012 Wildfire Games.
     1/* Copyright (C) 2013 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
    44 * 0 A.D. is free software: you can redistribute it and/or modify
     
    2222
    2323#include "simulation2/components/ICmpPlayerManager.h"
    2424#include "simulation2/components/ICmpPlayer.h"
     25#include "simulation2/components/ICmpOwnership.h"
    2526#include "simulation2/MessageTypes.h"
    2627
    2728#include "ps/Overlay.h"
     29#include "ps/Game.h"
    2830
    2931class CCmpMinimap : public ICmpMinimap
    3032{
    class CCmpMinimap : public ICmpMinimap  
    3335    {
    3436        componentManager.SubscribeToMessageType(MT_PositionChanged);
    3537        componentManager.SubscribeToMessageType(MT_OwnershipChanged);
     38        componentManager.SubscribeToMessageType(MT_PingOwner);
    3639    }
    3740
    3841    DEFAULT_COMPONENT_ALLOCATOR(Minimap)
    class CCmpMinimap : public ICmpMinimap  
    4851    bool m_Active;
    4952    entity_pos_t m_X, m_Z; // cache the latest position for more efficient rendering; only valid when m_Active true
    5053
     54
     55    // Used by the minimap while pinging this entity to indicate something (e.g. an attack)
     56    // Entity not pinged after MAX_PING_TURNS if it wasn't notified in between
     57    static const u32 MAX_PING_FRAMES = 500;
     58    bool m_PingEntity;
     59    u32 m_PingCount;
     60
     61
     62
    5163    static std::string GetSchema()
    5264    {
    5365        return
    class CCmpMinimap : public ICmpMinimap  
    8294    virtual void Init(const CParamNode& paramNode)
    8395    {
    8496        m_Active = true;
     97        m_PingEntity = false;
    8598
    8699        const CParamNode& colour = paramNode.GetChild("Colour");
    87100        if (colour.IsOk())
    class CCmpMinimap : public ICmpMinimap  
    183196
    184197            break;
    185198        }
     199        case MT_PingOwner:
     200        {
     201            // UNUSED: const CMessagePingOwner& data = static_cast<const CMessagePingOwner&> (msg);
     202
     203            if (!g_Game)
     204                break;
     205
     206            CmpPtr<ICmpOwnership> cmpOwnership(GetSimContext(), GetEntityId());
     207            if (!cmpOwnership)
     208                break;
     209            if(g_Game->GetPlayerID() != (int)cmpOwnership->GetOwner())
     210                break;
     211
     212            m_Active = true;
     213            m_PingEntity = true;
     214            m_PingCount = MAX_PING_FRAMES;
     215
     216            break;
     217        }
    186218        }
    187219    }
    188220
    class CCmpMinimap : public ICmpMinimap  
    198230        z = m_Z;
    199231        return true;
    200232    }
     233
     234    virtual bool IsEntityPinging(void)
     235    {
     236        if (!m_Active)
     237            return false;
     238
     239        return m_PingEntity;
     240    }
     241
     242    virtual u32 GetRemainingPingCount(void)
     243    {
     244        return m_PingCount;
     245    }
     246
     247    virtual void SetRemainingPingCount(u32 pingCount)
     248    {
     249        m_PingCount = pingCount;
     250
     251        if (m_PingCount == 0)
     252            m_PingEntity = false;
     253    }
    201254};
    202255
    203256REGISTER_COMPONENT_TYPE(Minimap)
  • source/simulation2/components/ICmpMinimap.h

    diff --git a/source/simulation2/components/ICmpMinimap.h b/source/simulation2/components/ICmpMinimap.h
    index e2ebf9b..fe906dd 100644
    a b class ICmpMinimap : public IComponent  
    3535     */
    3636    virtual bool GetRenderData(u8& r, u8& g, u8& b, entity_pos_t& x, entity_pos_t& z) = 0;
    3737
     38    /**
     39     * Returns true if the unit is pinging.
     40     */
     41    virtual bool IsEntityPinging(void) = 0;
     42
     43    /**
     44     * Returns the current ping count.
     45     */
     46    virtual u32 GetRemainingPingCount(void) = 0;
     47
     48    /**
     49     * Used by the minimap to set the ping count, controls pinging.
     50     */
     51    virtual void SetRemainingPingCount(u32 pingCount) = 0;
     52
    3853    DECLARE_INTERFACE_TYPE(Minimap)
    3954};
    4055
  • source/simulation2/scripting/MessageTypeConversions.cpp

    diff --git a/source/simulation2/scripting/MessageTypeConversions.cpp b/source/simulation2/scripting/MessageTypeConversions.cpp
    index c4109d7..9160b07 100644
    a b CMessage* CMessageVisionRangeChanged::FromJSVal(ScriptInterface& scriptInterface  
    336336    return new CMessageVisionRangeChanged(entity, oldRange, newRange);
    337337}
    338338
     339////////////////////////////////
     340
     341jsval CMessagePingOwner::ToJSVal(ScriptInterface& scriptInterface) const
     342{
     343    TOJSVAL_SETUP();
     344    return OBJECT_TO_JSVAL(obj);
     345}
     346
     347CMessage* CMessagePingOwner::FromJSVal(ScriptInterface& UNUSED(scriptInterface), jsval UNUSED(val))
     348{
     349    // FROMJSVAL_SETUP();
     350    return new CMessagePingOwner();
     351}
     352
    339353////////////////////////////////////////////////////////////////
    340354
    341355CMessage* CMessageFromJSVal(int mtid, ScriptInterface& scriptingInterface, jsval val)