• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[JASS] Leaks, Lag, and a Complete Freeze

Status
Not open for further replies.
Level 11
Joined
Aug 25, 2006
Messages
971
Ok, just thinking about this drives me as close to tears as I've been in a couple millennium. I heard about the neurabian loap, and that it had a way of building houses. I thought that was a great idea for the loap I've been working on for the past 1.5 years. So I leveled all house locations. Then I built this system.

This system pretty much allows a player to buy a plot of land. It gives the player a builder and also uses two separate methods to make sure the builder doesn't leave the property.

However when I implemented this system which I had worked so hard on it lagged! Much more then it had ever before! Eventually the game ground to a complete halt and froze.

I can't seem to reproduce the lag in single player. However in multiplayer its screamingly obvious. The second several people buy some plots of land and start building, it begins to lag. This lag builds up until the game freezes.

Heres the system code:
JASS:
struct SRealtorT
     rect plot
     boolean sold
     integer owner
endstruct
struct BPlayer
     rect plot
     unit realt
     real Setxb
     real Setyb
     unit builder
endstruct

globals
    //Remove this section during copy
    trigger gg_trg_SYS_Full
    unit gg_unit_n009_0106
    unit gg_unit_n009_0107
    rect gg_rct_HUS_2_Prop
    rect gg_rct_HUS_1_Prop
    trigger gg_trg_RunWayGate
    
    //Keep the rest
    BPlayer array AllPB 
    trigger GKnockback
    trigger GCheckCheck
    trigger GBuildTrack
    trigger GLeave
    group udg_CheckGroup
    boolean array udg_HAsBOught
endglobals

function INITHOUSE takes unit Realtor, rect landplot returns nothing
    local SRealtorT KA = SRealtorT.create()
    set KA.plot = landplot
    set KA.sold = false
    set KA.owner = 12
    call AttachInt(Realtor, "Struct", KA)
    //call SRealtorT.destroy(KA)     
    call TriggerRegisterLeaveRectSimple(GKnockback, landplot)
endfunction

function MHredo takes unit original returns unit
local real PosX = GetUnitX(original)
local real PosY = GetUnitY(original)
local player Owner = GetOwningPlayer(original)
local real facing = GetUnitFacing(original)
local integer utype = GetUnitTypeId(original)
    call RemoveUnit(original)

return CreateUnit(Owner, utype, PosX, PosY, facing)
endfunction

function IsUnitInRect takes unit u, rect r returns boolean
    local region reg = CreateRegion()
    local boolean b
    call RegionAddRect( reg, r )
    set b = IsUnitInRegion( reg, u )
    call RemoveRegion( reg )
    set reg = null
    return b
endfunction

function DestroyBuilder takes unit Builder returns nothing
    call GroupRemoveUnit(udg_CheckGroup, Builder) 
    call RemoveUnit(Builder)   
endfunction

function CreateBuilder takes unit Realtor, player Owner, rect Plot returns nothing
local real Gx = GetRectCenterX(Plot)
local real Gy = GetRectCenterY(Plot)
local unit totuni = CreateUnit(Owner,'u008', Gx, Gy, 120)
    set AllPB[GetPlayerId(Owner)].Setxb = Gx
    set AllPB[GetPlayerId(Owner)].Setyb = Gy
    set AllPB[GetPlayerId(Owner)].builder = totuni
    call GroupAddUnit(udg_CheckGroup, totuni)
    set totuni = null
    set Plot = null
endfunction

function CheckForDestroy takes nothing returns boolean
return (GetUnitAbilityLevel(GetFilterUnit(),'A024') == 0) 
endfunction

function RemoveHouse takes nothing returns nothing
local unit u = GetEnumUnit()
local integer ma = R2I(I2R(GetUnitPointValue(u)) * .8)
local integer ka = GetPlayerState(GetOwningPlayer(u), PLAYER_STATE_RESOURCE_GOLD) + ma
    call SetPlayerState(GetOwningPlayer(u), PLAYER_STATE_RESOURCE_GOLD, ka)
    call KillUnit(u)
    call DisplayTimedTextToPlayer(GetOwningPlayer(u),0,0,60,"|c0000F4F4You get " + I2S(ma) + " for selling a " + GetObjectName(GetUnitTypeId(u)) + "|r")
    call RemoveUnit(u)
    set u = null
endfunction

function Trig_SYS_Full_Actions takes nothing returns nothing
local unit Morg = GetSellingUnit()
local SRealtorT Norm
local player Meor = GetOwningPlayer(GetBuyingUnit())
local integer Ityped = GetItemTypeId(GetSoldItem()) 
    if (Ityped =='I00A') or (Ityped == 'I009') then 
        set Norm = SRealtorT( GetAttachedInt(Morg,"Struct"))
        if Norm.sold then
            call DisplayTextToForce(GetForceOfPlayer(Meor),"|c00F27900Someone has already bought this land, try a different location")
        else
            if udg_HAsBOught[GetPlayerId(Meor)] then
               call DisplayTextToForce(GetForceOfPlayer(Meor),"|c00F27900You can only own one property at a time")
            else        
                call CreateBuilder(Morg, Meor, Norm.plot)
                set Norm.sold = true
                set Norm.owner = GetPlayerId(Meor)
                set udg_HAsBOught[GetPlayerId(Meor)] = true
                set AllPB[GetPlayerId(Meor)].plot = Norm.plot 
                set AllPB[GetPlayerId(Meor)].realt = Morg
                call DisplayTextToForce(GetForceOfPlayer(Meor),"|c00F27900You have bought a plot of land, you can now use the builder to build a house.")
            endif
        endif
            call AttachInt(Morg, "Struct", Norm)
           // call SRealtorT.destroy(Norm)
            call TriggerSleepAction(.29)
            call RemoveItem(GetSoldItem())
    else
        if Ityped == 'I00B' then
            set Norm = SRealtorT( GetAttachedInt(Morg,"Struct"))
            if Meor == Player(Norm.owner) then
                set udg_HAsBOught[GetPlayerId(Meor)] = false
                call DestroyBuilder(AllPB[GetPlayerId(Meor)].builder)
                set Norm.sold = false
                call DisplayTextToForce(GetForceOfPlayer(Meor),"|c00F27900You have now sold all your land.")
                call SetPlayerState(Meor, PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(Meor, PLAYER_STATE_RESOURCE_GOLD) + 400)
                call ForGroup( GetUnitsOfPlayerMatching(Player(0), Condition(function CheckForDestroy)), function RemoveHouse )    
            else
                call DisplayTextToForce(GetForceOfPlayer(Meor),"|c00F27900You do not own this land, so you can not sell it.")
            endif
            call AttachInt(Morg, "Struct", Norm)
           // call SRealtorT.destroy(Norm)
            call TriggerSleepAction(.29)
            call RemoveItem(GetSoldItem())
        endif    
    endif
    set Morg = null
    set Meor = null
endfunction



function RestPost takes nothing returns nothing
return (IsUnitInGroup(GetTriggerUnit(),udg_CheckGroup))  
endfunction

function CheckPost takes nothing returns boolean
return(IsUnitInGroup(GetTriggerUnit(),udg_CheckGroup))
endfunction


function CheckLoc takes nothing returns nothing
local unit u = GetEnumUnit()
local integer r = GetPlayerId(GetOwningPlayer(u)) 
    if IsUnitInRect(u,AllPB[r].plot) == false then
        call SetUnitX(u, AllPB[r].Setxb)
        call SetUnitY(u, AllPB[r].Setyb)
        call IssueImmediateOrder(u, "stop")
    endif
    set u = null   
endfunction

function CheckThem takes nothing returns nothing 
    call ForGroup(udg_CheckGroup, function CheckLoc)
endfunction


   
//===========================================================================
function InitTrig_SYS_Full takes nothing returns nothing
    local integer int= 11
    set gg_trg_SYS_Full = CreateTrigger(  )
    set GKnockback = CreateTrigger()
    set GCheckCheck = CreateTrigger()  //NotAlly
    call TriggerAddAction(GCheckCheck, function CheckThem)
    call TriggerRegisterTimerEvent(GCheckCheck, 2, true)
    call TriggerAddCondition( GKnockback, Condition( function CheckPost ) )
    call TriggerAddAction( GKnockback, function RestPost )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_SYS_Full, EVENT_PLAYER_UNIT_SELL_ITEM )
    call TriggerAddAction( gg_trg_SYS_Full, function Trig_SYS_Full_Actions )
    loop
    exitwhen int == 0
        set udg_HAsBOught[int]=false
        set AllPB[int] = BPlayer.create()
    set int = int - 1
    endloop
    set udg_CheckGroup = CreateGroup()
    call INITHOUSE(gg_unit_n009_0107 , gg_rct_HUS_2_Prop)
    call INITHOUSE(gg_unit_n009_0106 , gg_rct_HUS_1_Prop)
    //call INITHOUSE(gg_unit_n009_0013 , gg_rct_HUS_3_Prop)
    //call INITHOUSE(gg_unit_n009_0111 , gg_rct_HUS_4_Prop)
    //call INITHOUSE(gg_unit_n009_0108 , gg_rct_HUS_5_Prop)
    //call INITHOUSE(gg_unit_n009_0112 , gg_rct_HUS_6_Prop)
endfunction
 //Everything below this is a seperate trigger, but still part of the 'house system'

function Trig_RunWayGate_Conditions takes nothing returns boolean
return ( GetSpellAbilityId() == 'A02E' )
endfunction

function Trig_RunWayGate_Actions takes nothing returns nothing
local unit Runer = GetSpellAbilityUnit()
local player Orth = GetOwningPlayer(Runer)
local integer r = GetPlayerId(GetOwningPlayer(u)) 
local region Mok = CreateRegion()
local location Nork = GetSpellTargetLoc()
    call RegionAddRect(Mok, AllPB[r].plot)
    if IsPointInRegion(Mok, GetLocationX(Nork),GetLocationY(Nork)) then
        call UnitRemoveAbility(Runer, 'A02E')
        call WaygateSetDestination(Runer, GetLocationX(Nork), GetLocationY(Nork))    
        call WaygateActivate(Runer,true)
    else
        call IssueImmediateOrder(Runer, "stop")
        call DisplayTextToPlayer(Orth, 0,0, "You must target a location within your property!")
    endif
    set Runer = null
    set Orth = null
    call RemoveRegion(Mok)
    call RemoveLocation(Nork)
endfunction

//===========================================================================
function InitTrig_RunWayGate takes nothing returns nothing
    set gg_trg_RunWayGate = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_RunWayGate, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_RunWayGate, Condition( function Trig_RunWayGate_Conditions ) )
    call TriggerAddAction( gg_trg_RunWayGate, function Trig_RunWayGate_Actions )
endfunction
All the code after
JASS:
 //Everything below this is a seperate trigger, but still part of the 'house system'
is actually there to make a special building you can buy for your house (waygate) work. It has nothing to do with buying/selling the house, however it uses some of the same values.

This system makes me very sad, if you'd spend some time and look into it I'd be very appreciative.

Its missing about 8 global declarations, ignore that. Those declarations are added elsewhere in the game.
 
Last edited:
Level 11
Joined
Aug 25, 2006
Messages
971
Its only one cache per house added, which with 6 houses added. Thats 6 caches! Also there meant to be perminant, thats why I don't flush them. There used every time a player buys/sells a house.

Edit: Woops! Sorry I realized I had posted an older version of the code. Check again.
 
Status
Not open for further replies.
Top