Difference between revisions of "ConflictSystem"

From Legends of Aria Admin and Modding Wiki
Jump to: navigation, search
(ConflictRelations Table)
(UpdateConflictRelation)
Line 134: Line 134:
  
 
=== UpdateConflictRelation ===
 
=== UpdateConflictRelation ===
 +
''
 +
  -- Update the conflict relation between two mobiles, also cleans mobileA's conflict
 +
    table of any expired.
 +
  -- @param mobileA(mobileObj)
 +
  -- @param mobileB(mobileObj)
 +
  -- @param newRelation(luaTable) the entry from ConflictRelations
 +
  -- @param guardCheck(boolean) If true, this update will check for guard protection,
 +
      this way you can refresh a conflict on both sides but only one will cares about
 +
      guards.
 +
  -- @return none
 +
 +
  function UpdateConflictRelation(mobileA, mobileB, newRelation, guardCheck)
 +
    if ( newRelation == nil ) then
 +
        LuaDebugCallStack("[Conflict] Nil conflict relation table provided")
 +
        return
 +
    end
 +
    if ( newRelation.Name == nil ) then
 +
        LuaDebugCallStack("[Conflict] Invalid conflict relation table, missing Name")
 +
        return
 +
    end
 +
    if ( mobileA == nil ) then
 +
        LuaDebugCallStack("[Conflict] Nil mobileA provided.")
 +
        return
 +
    end
 +
    if ( mobileB == nil ) then
 +
        LuaDebugCallStack("[Conflict] Nil mobileB provided.")
 +
        return
 +
    end
 +
    local tableA = GetConflictTable(mobileA)
 +
    local wasGuardIgnored = false
 +
    if ( not guardCheck and tableA[mobileB] ~= nil and tableA[mobileB][3] ) then
 +
        wasGuardIgnored = true
 +
    end
 +
    -- set/update the conflict
 +
    local now = DateTime.UtcNow
 +
    tableA[mobileB] = {newRelation.Name}
 +
    -- when the conflict should end
 +
    if ( newRelation.Warning == true ) then
 +
        tableA[mobileB][2] = now + ServerSettings.Conflict.WarningDuration
 +
    else
 +
        tableA[mobileB][2] = now + ServerSettings.Conflict.RelationDuration
 +
    end
 +
    -- cleanse table of any expired.
 +
    for k,v in pairs(tableA) do
 +
        if ( now >= v[2] ) then
 +
            -- it's expired
 +
            tableA[k] = nil
 +
        end
 +
    end
 +
    if ( ConflictEquals(newRelation.Name, ConflictRelations.Aggressor) and
 +
        IsPlayerCharacter(mobileA) and IsPlayerCharacter(mobileB)) then
 +
        -- mobileB has zero karma concequences against mobileA
 +
        -- Turn mobileA AGGRESSIVE on mobileB's client (so B is looking at an aggressive
 +
        A)
 +
        mobileA:SendClientMessage("UpdateMobileConflictStatus",
 +
        {mobileB,"Aggressor",ServerSettings.Conflict.RelationDuration.TotalSeconds})
 +
        mobileB:SendClientMessage("UpdateMobileConflictStatus",
 +
        {mobileA,"Aggressed",ServerSettings.Conflict.RelationDuration.TotalSeconds})
 +
        -- 100
 +
    elseif ( ConflictEquals(newRelation.Name, ConflictRelations.Warning) and
 +
            IsPlayerCharacter(mobileA) and IsPlayerCharacter(mobileB) ) then
 +
        -- mobileA is nearly an aggressor to mobileB
 +
        -- Turn mobileB YELLOW on mobileA's client (so A is looking at a mobile they
 +
            know if they hit again they are an aggressor)
 +
        mobileA:SendClientMessage("UpdateMobileConflictStatus",
 +
        {mobileB,"Warning",ServerSettings.Conflict.WarningDuration.TotalSeconds})
 +
    end
 +
    --[[
 +
        Handle Guard protection triggers for aggressive actions.
 +
    ]]
 +
    -- if mobileA's relation is aggressor
 +
    if ( guardCheck and ConflictEquals(newRelation.Name, ConflictRelations.Aggressor) )
 +
      then
 +
        local karmaBLevel = GetKarmaLevel(GetKarma(mobileB))
 +
        local guardIgnore = true
 +
        -- if mobileB's karma level is guard protected
 +
        if ( karmaBLevel.GuardProtectPlayer or karmaBLevel.GuardProtectNPC ) then
 +
            local isPlayerB = IsPlayerCharacter(mobileB)
 +
            if ( (isPlayerB and karmaBLevel.GuardProtectPlayer)
 +
            or (not isPlayerB and karmaBLevel.GuardProtectNPC) ) then
 +
                -- make the guards protect B from A
 +
                GuardProtect(mobileB, mobileA)
 +
                guardIgnore = false
 +
            end
 +
        end
 +
        -- if guards don't protect mobileB's karma level, add an ignore guard entry
 +
        -- (This is so, for example, players can be aggressors against an outcast, but
 +
          guards won't attack them for being aggressors against outcasts)
 +
        if ( guardIgnore == true ) then
 +
            tableA[mobileB][3] = true
 +
        end
 +
    end
 +
    -- when skipping guard protect this value would be ignored and overwritten if not
 +
      cached from previous data.
 +
    if ( wasGuardIgnored ) then
 +
        tableA[mobileB][3] = true
 +
    end
 +
    -- save the updated conflict table for the mobile
 +
    SetConflictTable(mobileA, tableA)
 +
  end
 +
''
 +
 
=== ConflictEquals ===
 
=== ConflictEquals ===
 
=== AdvanceConflictRelation ===
 
=== AdvanceConflictRelation ===

Revision as of 08:11, 27 January 2018

 welcome this will discuss the contents of the globals\helpers\conflict.lua
 this documentation is correct as of version 6.0 PRECB1 Release 

ConflictRelations Table

 ConflictRelations = {
   Warning = {
       Name = "Warning",
       Warning = true,
   },
   BeenWarned = {
       Name = "BeenWarned",
       Warning = true,
   },
   Aggressor = {
       Name = "Aggressor",
   },
   Victim = {
       Name = "Victim"
   },
   Defender = {
       Name = "Defender"
   }
 }

Conflict Functions

GetConflictTable

 -- Get the conflict table for a mobile
 -- @param mobile(mobileObj)
 -- @return luaTable containing all conflicts for this mobile
 function GetConflictTable(mobile)
   if ( mobile == nil or not mobile ) then
       LuaDebugCallStack("[Conflict] Invalid mobile provided.")
       return {}
   end
   return mobile:GetObjVar("Conflicts") or {}
 end

ClearConflictTable

 -- Clear the conflict table of a mobile
 -- @param mobile(mobileObj)
 -- @return none
 function ClearConflictTable(mobile, isPlayer)
   if ( mobile == nil or not mobile ) then
       LuaDebugCallStack("[Conflict] Invalid mobile provided.")
       return
   end
   if ( mobile:HasObjVar("Conflicts") ) then
       mobile:DelObjVar("Conflicts")
   end
   if ( isPlayer == true ) then
       InitializeClientConflicts(mobile)
   end
 end

SetConflictTable

 -- Set the conflict table for a mobile
 -- @param mobile(mobileObj)
 -- @param data(luaTable)
 -- @return none
 function SetConflictTable(mobile, data)
   mobile:SetObjVar("Conflicts", data)
 end

FreezeConflictTable

 --- Freeze the conflict table on a mobile, optionally saving the frozen table on a 
 different object. Will clear all conflicts for the mobile if target does not equal 
 mobile.
 -- @param mobile(mobileObj)
 -- @param target(gameObj)(optional) the gameObj the conflict table will be saved to
 -- @return none
 function FreezeConflictTable(mobile, target)
   target = target or mobile
   local conflictTable = GetConflictTable(mobile)
   for mobileId,conflict in pairs(conflictTable) do
       -- set all the expires to true, meaning they never expire
       conflictTable[mobileId][2] = true
   end
   -- save the frozen table on the target
   SetConflictTable(target, conflictTable)
 end

GetConflictRelation

 -- Get the relation of conflict mobileA is to mobileB.
 -- @param mobileA(mobileObj)
 -- @param mobileB(mobileObj)
 -- @param mobileAConflictTable(optional) return value from GetConflictTable()
 -- @return One of ConflictRelations, nil if not-found/expired.
 function GetConflictRelation(mobileA, mobileB, mobileAConflictTable)
   mobileAConflictTable = mobileAConflictTable or GetConflictTable(mobileA) or {}
   -- only valid, frozen/non-expired, will make the cut.
   if ( ValidConflictRelationTable(mobileAConflictTable[mobileB]) ) then
       return mobileAConflictTable[mobileB][1]
   end
   return nil
 end

ValidConflictRelationTable

 --- Validate a conflict relation table (make sure it's not expired)
 -- @param conflictRelationTable(luaTable) A single entry from return value 
    GetConflictTable()
 -- @return true if valid, false if not
 function ValidConflictRelationTable(conflictRelationTable)
   return (
       conflictRelationTable ~= nil
       and
       (
           -- frozen
           conflictRelationTable[2] == true
           or
           -- or non-expired
           DateTime.UtcNow < conflictRelationTable[2]
       )
   )
 end

UpdateConflictRelation

 -- Update the conflict relation between two mobiles, also cleans mobileA's conflict 
    table of any expired.
 -- @param mobileA(mobileObj)
 -- @param mobileB(mobileObj)
 -- @param newRelation(luaTable) the entry from ConflictRelations
 -- @param guardCheck(boolean) If true, this update will check for guard protection, 
     this way you can refresh a conflict on both sides but only one will cares about 
     guards.
 -- @return none
 function UpdateConflictRelation(mobileA, mobileB, newRelation, guardCheck)
   if ( newRelation == nil ) then
       LuaDebugCallStack("[Conflict] Nil conflict relation table provided")
       return
   end
   if ( newRelation.Name == nil ) then
       LuaDebugCallStack("[Conflict] Invalid conflict relation table, missing Name")
       return
   end
   if ( mobileA == nil ) then
       LuaDebugCallStack("[Conflict] Nil mobileA provided.")
       return
   end
   if ( mobileB == nil ) then
       LuaDebugCallStack("[Conflict] Nil mobileB provided.")
       return
   end
   local tableA = GetConflictTable(mobileA)
   local wasGuardIgnored = false
   if ( not guardCheck and tableA[mobileB] ~= nil and tableA[mobileB][3] ) then
       wasGuardIgnored = true
   end
   -- set/update the conflict
   local now = DateTime.UtcNow
   tableA[mobileB] = {newRelation.Name}
   -- when the conflict should end
   if ( newRelation.Warning == true ) then
       tableA[mobileB][2] = now + ServerSettings.Conflict.WarningDuration
   else
       tableA[mobileB][2] = now + ServerSettings.Conflict.RelationDuration
   end
   -- cleanse table of any expired.
   for k,v in pairs(tableA) do
       if ( now >= v[2] ) then
           -- it's expired
           tableA[k] = nil
       end
   end
   if ( ConflictEquals(newRelation.Name, ConflictRelations.Aggressor) and 
        IsPlayerCharacter(mobileA) and IsPlayerCharacter(mobileB)) then
       -- mobileB has zero karma concequences against mobileA
       -- Turn mobileA AGGRESSIVE on mobileB's client (so B is looking at an aggressive 
       A)
       mobileA:SendClientMessage("UpdateMobileConflictStatus",
       {mobileB,"Aggressor",ServerSettings.Conflict.RelationDuration.TotalSeconds})
       mobileB:SendClientMessage("UpdateMobileConflictStatus",
       {mobileA,"Aggressed",ServerSettings.Conflict.RelationDuration.TotalSeconds})
       -- 100
   elseif ( ConflictEquals(newRelation.Name, ConflictRelations.Warning) and 
            IsPlayerCharacter(mobileA) and IsPlayerCharacter(mobileB) ) then
       -- mobileA is nearly an aggressor to mobileB
       -- Turn mobileB YELLOW on mobileA's client (so A is looking at a mobile they 
           know if they hit again they are an aggressor)
       mobileA:SendClientMessage("UpdateMobileConflictStatus",
       {mobileB,"Warning",ServerSettings.Conflict.WarningDuration.TotalSeconds})
   end
   --[[
       Handle Guard protection triggers for aggressive actions.
   ]]
   -- if mobileA's relation is aggressor
   if ( guardCheck and ConflictEquals(newRelation.Name, ConflictRelations.Aggressor) ) 
     then
       local karmaBLevel = GetKarmaLevel(GetKarma(mobileB))
       local guardIgnore = true
       -- if mobileB's karma level is guard protected
       if ( karmaBLevel.GuardProtectPlayer or karmaBLevel.GuardProtectNPC ) then
           local isPlayerB = IsPlayerCharacter(mobileB)
           if ( (isPlayerB and karmaBLevel.GuardProtectPlayer)
           or (not isPlayerB and karmaBLevel.GuardProtectNPC) ) then
               -- make the guards protect B from A
               GuardProtect(mobileB, mobileA)
               guardIgnore = false
           end
       end
       -- if guards don't protect mobileB's karma level, add an ignore guard entry
       -- (This is so, for example, players can be aggressors against an outcast, but 
          guards won't attack them for being aggressors against outcasts)
       if ( guardIgnore == true ) then
           tableA[mobileB][3] = true
       end
   end
   -- when skipping guard protect this value would be ignored and overwritten if not 
      cached from previous data.
   if ( wasGuardIgnored ) then
       tableA[mobileB][3] = true
   end
   -- save the updated conflict table for the mobile
   SetConflictTable(mobileA, tableA)
 end

ConflictEquals

AdvanceConflictRelation

ForeachAggressor

IsAggressor

IsMobTaggedBy

TagMob

InheritAggressivePlayerConflicts

GetNearbyTaggedMobiles

InitializeClientConflicts