Posté le: 18/03/10 20:11 Sujet du message: Optimisation: Trade 2.0
Je créé un nouveau sujet (l'autre est blindé de trucs inutiles et la flemme de tout nettoyer).
Maintenant, je n'ai plus besoin de trigger périodique pour donner des ordres aux cargos qui doivent se balader entre deux Freeports.
En revanche, dans le cadre d'une TradeRoad, je n'arrive pas à me passer de Timers pour détecter si les deux freeports reliés par la TradeRoad sont vivants (le cas échéant, je supprime la traderoad).
La difficulté est double:
-ces monstres de "doubles listes chaînées"
-comment, à la mort de l'un des deux freeports, détecter l'ensemble des traderoad associées au freeport mourant, et les supprimer (ainsi que l'ensemble des portails qui les relient)
destructable gate
unit targetFreeport = null
unit playerFreeport = null
method destroy takes nothing returns nothing
set .targetFreeport = null
set .playerFreeport = null
call KillDestructable(.gate)
set .gate = null
endmethod
endstruct
private struct s_RoadSystem
unit targetFreeport = null
unit playerFreeport = null
boolean road = false
static method operator [] takes unit u returns thistype
return thistype(GetUnitId(u))
endmethod
method destroy takes nothing returns nothing
local integer i = 0
set .targetFreeport = null
set .playerFreeport = null
set .road = false
endmethod
endstruct
private struct s_TradeSys
unit targetFreeport = null
unit playerFreeport = null
static method operator [] takes unit u returns thistype
return thistype(GetUnitId(u))
endmethod
method destroy takes nothing returns nothing
set .targetFreeport = null
set .playerFreeport = null
endmethod
endstruct
private function CheckRoadValidity takes nothing returns nothing
local timer t = GetExpiredTimer()
local s_GateSystem this = GetTimerData(t)
if GetUnitState(this.playerFreeport,UNIT_STATE_LIFE)<=0 or GetUnitState(this.targetFreeport,UNIT_STATE_LIFE)<=0 or this.targetFreeport == null or this.playerFreeport == null then
call ReleaseTimer(t)
call this.destroy()
endif
endfunction
private function RunGate takes unit playerFreeport, unit targetFreeport,destructable gate returns nothing
local timer t = NewTimer()
local s_GateSystem this = s_GateSystem.create()
set this.playerFreeport = playerFreeport
set this.targetFreeport = targetFreeport
set this.gate = gate
call SetTimerData(t, this)
call TimerStart (t, 5., true, function CheckRoadValidity )
endfunction
private function CheckSpeedBonus takes unit cargo, boolean add returns nothing
if add==true and GetUnitAbilityLevel(cargo,SPEEDBONUS)<=0 then
call UnitAddAbility(cargo,SPEEDBONUS)
elseif add==false and GetUnitAbilityLevel(cargo,SPEEDBONUS)>=1 then
call UnitRemoveAbility(cargo,SPEEDBONUS)
endif
endfunction
private function InitializeRoad takes unit playerFreeport,unit targetFreeport returns nothing
local s_RoadSystem this = s_RoadSystem[playerFreeport]
set this.targetFreeport = targetFreeport
set this.playerFreeport = playerFreeport
set this.road = true
endfunction
private function CreateTradeRoad takes nothing returns nothing
local integer i = 0
local unit roadCreator = SpellEvent.CastingUnit
local unit roadTarget = SpellEvent.TargetUnit
local player owner = GetOwningPlayer(roadCreator)
local real x1 = GetUnitX(roadCreator)
local real y1 = GetUnitY(roadCreator)
local real x2 = GetUnitX(roadTarget)
local real y2 = GetUnitY(roadTarget)
local real angle = Atan2((y2 -y1), (x2 - x1))
local real distance = SquareRoot((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1))
local destructable gate = null
if IsPlayerEnemy(owner,GetOwningPlayer(roadTarget))==false then
if GetUnitTypeId(roadTarget)==FREEPORT then
if GetPlayerState(owner,PLAYER_STATE_RESOURCE_LUMBER)>= 500 then
call SetPlayerState(owner, PLAYER_STATE_RESOURCE_LUMBER, GetPlayerState(owner,PLAYER_STATE_RESOURCE_LUMBER)-500)
call InitializeRoad(roadCreator,roadTarget)
call InitializeRoad(roadTarget,roadCreator)
loop
set i = i + 1
exitwhen i > distance/INTERVAL
set x2 = x1 + i*INTERVAL*Cos(angle)
set y2 = y1 + i*INTERVAL*Sin(angle)
set gate = CreateDestructable(GATE,x2,y2,angle*bj_RADTODEG,0.5,0)
call RunGate(roadCreator,roadTarget,gate)
endloop
set roadCreator = null
set roadTarget = null
set owner = null
set gate = null
return
else
call ErrorSound(owner)
call DisplayTextToPlayer(owner,0,0,G3)
endif
else
call ErrorSound(owner)
call DisplayTextToPlayer(owner,0,0,G1)
endif
else
call ErrorSound(owner)
call DisplayTextToPlayer(owner,0,0,G1)
endif
set roadCreator = null
set roadTarget = null
set owner = null
set gate = null
endfunction
private function IsFreeportAlive takes unit cargo returns boolean
local s_TradeSys this = s_TradeSys[cargo]
if GetUnitState(this.playerFreeport,UNIT_STATE_LIFE)>0 and GetUnitState(this.targetFreeport,UNIT_STATE_LIFE)>0 then
return true
else
call IssueImmediateOrder(cargo,TRADEABORTORDER)
return false
endif
endfunction
private function BuyOrder takes unit cargo returns nothing
local s_TradeSys this = s_TradeSys[cargo]
local s_RoadSystem dat = s_RoadSystem[this.playerFreeport]
if IsFreeportAlive(cargo)==true then
if dat.road==true then
call CheckSpeedBonus(cargo,true)
else
call CheckSpeedBonus(cargo,false)
endif
call IssueTargetOrder(cargo,BUYORDER,this.playerFreeport)
else
call IssueImmediateOrder(cargo,TRADEABORTORDER)
endif
endfunction
private function SellOrder takes unit cargo returns nothing
local s_TradeSys this = s_TradeSys[cargo]
local s_RoadSystem dat = s_RoadSystem[this.targetFreeport]
if IsFreeportAlive(cargo)==true then
if dat.road==true then
call CheckSpeedBonus(cargo,true)
else
call CheckSpeedBonus(cargo,false)
endif
call IssueTargetOrder(cargo,SELLORDER,this.targetFreeport)
else
call IssueImmediateOrder(cargo,TRADEABORTORDER)
endif
endfunction
private function GetProductAmount takes unit cargo returns integer
local integer i = 0
local item carriedItem = null
local integer carriedItemCharges = 0
loop
exitwhen i > 5
set carriedItem = UnitItemInSlot(cargo, i)
if GetItemTypeId(carriedItem) == PRODUCT then
set carriedItemCharges = GetItemCharges(carriedItem)
set carriedItem = null
return carriedItemCharges
endif
set i = i + 1
endloop
set carriedItem = null
return 0
endfunction
private function BuyOperation takes nothing returns nothing
local unit cargo = SpellEvent.CastingUnit
local s_TradeSys this = s_TradeSys[cargo]
local integer i = 0
local integer slotAmount = GetPlayerTechCount(GetOwningPlayer(cargo),CARGOSLOT,true)
local item carriedItem = null
loop
exitwhen i > 5
set carriedItem = UnitItemInSlot(cargo, i)
if GetItemTypeId(carriedItem) == PRODUCT and GetItemCharges(carriedItem)<=slotAmount then
call SetItemCharges(carriedItem,slotAmount)
endif
set i = i + 1
endloop
call DestroyEffect(AddSpecialEffectTarget(FXLOAD,cargo,"origin"))
call SellOrder(cargo)
set carriedItem = null
set cargo = null
endfunction
private function SellOperation takes nothing returns nothing
local unit cargo = SpellEvent.CastingUnit
local s_TradeSys this = s_TradeSys[cargo]
local integer productAmount = GetProductAmount(cargo)
local real dx = GetUnitX(this.playerFreeport)-GetUnitX(this.targetFreeport)
local real dy = GetUnitY(this.playerFreeport)-GetUnitY(this.targetFreeport)
local real distanteBetweenPorts = SquareRoot(dx*dx+dy*dy)
local integer gold = R2I(distanteBetweenPorts*0.05*0.05)*productAmount*2
local integer lumber = R2I(distanteBetweenPorts*0.02*0.05)*productAmount*2
local item carriedItem = null
local player owner = GetOwningPlayer(cargo)
local integer ownerId = GetPlayerId(owner)
local integer i = 0
loop
exitwhen i > 5
set carriedItem = UnitItemInSlot(cargo, i)
if GetItemTypeId(carriedItem) == PRODUCT then
call SetItemCharges(carriedItem,0)
endif
set i = i + 1
endloop
call DestroyEffect(AddSpecialEffectTarget(FXUNLOAD,cargo,"origin"))
//Bonus added if the owner of the cargo is a Merchant
if Merchant[GetPlayerId(owner)]== true then
set gold = R2I(gold*1.15)
set lumber = R2I(lumber*1.15)
endif
//Other bonuses for Merchant, if they have chosen a Merchant Mothership
if GetUnitTypeId(cargo)==CARGOCRUISER then
set gold = R2I(gold*10.)
set lumber = R2I(lumber*10.)
elseif GetUnitTypeId(cargo)==CARGOMOTHERSHIP1 then
set gold = R2I(gold*(5.+MsSys(owner).CountCargoMod()))
set lumber = R2I(lumber*(5.+MsSys(owner).CountCargoMod()))
elseif GetUnitTypeId(cargo)==CARGOMOTHERSHIP2 then
set gold = R2I(gold*(8.+MsSys(owner).CountCargoMod()))
set lumber = R2I(lumber*(8.+MsSys(owner).CountCargoMod()))
elseif GetUnitTypeId(cargo)==CARGOMOTHERSHIP3 then
set gold = R2I(gold*(13.+MsSys(owner).CountCargoMod()))
set lumber = R2I(lumber*(13.+MsSys(owner).CountCargoMod()))
endif
//Add the earned resources to the owner of the cargo, play a sound and display the earned resources
call SetResource(owner,gold,lumber)
call RunSoundOnUnit(SOUND_GOLD,cargo)
call Text(cargo,false,C1+I2S(gold)+C+" p, "+C2+I2S(lumber)+C+" i")
//If the owner of the cargo is a merchant, raises the experience points (rank system)
if Merchant[ownerId]==true then
call UpdateRank(owner,XP_TRADE)
endif
call BuyOrder(cargo)
set owner = null
set carriedItem = null
set cargo = null
endfunction
private function ReloadOrder takes unit cargo returns nothing
if GetProductAmount(cargo)>=1 then
call SellOrder(cargo)
else
call BuyOrder(cargo)
endif
endfunction
private function ReceiveOrder takes nothing returns boolean
local unit cargo = GetTriggerUnit()
local string s = OrderId2String(GetIssuedOrderId())
if s!=BUYORDER and s!=SELLORDER and s!=TRADEABORTORDER and GetUnitAbilityLevel(cargo,TRADEABORTID)>=1 then
call ReloadOrder(cargo)
endif
set cargo = null
return false
endfunction
private function ResetCargo takes unit cargo returns nothing
call UnitRemoveAbility(cargo,TRADEABORTID)
call UnitRemoveAbility(cargo,SELLID)
call UnitRemoveAbility(cargo,BUYID)
call UnitAddAbility(cargo,SELECTBUYER)
call CheckSpeedBonus(cargo,false)
endfunction
private function AbortTrade takes nothing returns nothing
local s_TradeSys this = s_TradeSys[SpellEvent.CastingUnit]
call this.destroy()
call ResetCargo(SpellEvent.CastingUnit)
endfunction
private function InitializeTrade takes unit cargo,unit targetFreeport returns nothing
local s_TradeSys this = s_TradeSys[cargo]
local player owner = GetOwningPlayer(cargo)
set this.targetFreeport = targetFreeport
set this.playerFreeport = Freeport[GetPlayerId(owner)]
call UnitRemoveAbility(cargo,SELECTBUYER)
call UnitAddAbility(cargo,TRADEABORTID)
call UnitAddAbility(cargo,SELLID)
call UnitAddAbility(cargo,BUYID)
call BuyOrder(cargo)
endfunction
private function SelectTradeTarget takes nothing returns nothing
local unit cargo = SpellEvent.CastingUnit
local unit buyer = SpellEvent.TargetUnit
local player owner = GetOwningPlayer(cargo)
local integer ownerId = GetPlayerId(owner)
if IsPlayerEnemy(owner,GetOwningPlayer(buyer))==false then
if GetUnitTypeId(buyer)==FREEPORT then
if buyer != Freeport[ownerId] then
call InitializeTrade(cargo,buyer)
else
call ErrorSound(owner)
call DisplayTextToPlayer(owner,0,0,M3)
endif
set cargo = null
set buyer = null
set owner = null
return
else
call ErrorSound(owner)
call DisplayTextToPlayer(owner,0,0,M1)
endif
else
call ErrorSound(owner)
call DisplayTextToPlayer(owner,0,0,M1)
endif
set cargo = null
set buyer = null
set owner = null
endfunction
private function AddProductsToEnteringShips takes nothing returns boolean
local unit entering = GetTriggerUnit()
local integer enteringId = GetUnitTypeId(entering)
local item product = null
if enteringId == CARGOSHUTTLE then
set product = CreateItem(PRODUCT,0.,0.)
call SetItemCharges(product,0)
call UnitAddItem(entering,product)
endif
set product = null
set entering = null
return false
endfunction
private function RemoveRoad takes unit freeport returns nothing
local s_RoadSystem this = s_RoadSystem[freeport]
call this.destroy()
endfunction
private function FreeportKilled takes nothing returns boolean
local unit killedUnit = GetTriggerUnit()
if GetUnitTypeId(killedUnit)==FREEPORT then
set Freeport[GetPlayerId(GetOwningPlayer(killedUnit))] = null
call RemoveRoad(killedUnit)
endif
set killedUnit = null
return false
endfunction
private function FreeportCreated takes nothing returns boolean
local unit constructed = GetConstructedStructure()
if GetUnitTypeId(constructed)==FREEPORT then
set Freeport[GetPlayerId(GetOwningPlayer(constructed))] = constructed
endif
set constructed = null
return false
endfunction
private function init takes nothing returns nothing
local trigger t1 = CreateTrigger()
local trigger t2 = CreateTrigger()
local trigger t3 = CreateTrigger()
local trigger t4 = CreateTrigger()
call AbilityPreload(CARGOSLOT)
call AbilityPreload(TRADEABORTID)
call AbilityPreload(SELECTBUYER)
call AbilityPreload(SELLID)
call AbilityPreload(BUYID)
call RemoveItem(CreateItem(PRODUCT,0.,0.))//antileak
call TriggerRegisterEnterRectSimple(t1, bj_mapInitialPlayableArea)//other events
call TriggerAddCondition( t1, Condition( function AddProductsToEnteringShips ) )
call TriggerRegisterAnyUnitEventBJ(t2, EVENT_PLAYER_UNIT_CONSTRUCT_FINISH )
call TriggerAddCondition(t2, Condition(function FreeportCreated))
call TriggerRegisterAnyUnitEventBJ(t3, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
call TriggerRegisterAnyUnitEventBJ(t3, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER )
call TriggerRegisterAnyUnitEventBJ(t3, EVENT_PLAYER_UNIT_ISSUED_ORDER )
//call TriggerAddCondition(t3, Condition(function ReceiveOrder))
call TriggerRegisterAnyUnitEventBJ(t4, EVENT_PLAYER_UNIT_DEATH )
call TriggerAddCondition(t4, Condition(function FreeportKilled))
call RegisterSpellEffectResponse(SELECTBUYER,SelectTradeTarget)//when cargo use Select a Buyer skill
call RegisterSpellFinishResponse(TRADEABORTID,AbortTrade)//when cargo use Abort Trade skill
call RegisterSpellFinishResponse(SELLID,SellOperation)
call RegisterSpellFinishResponse(BUYID,BuyOperation)
call RegisterSpellCastResponse(CREATETRADEROAD,CreateTradeRoad) //gate system
endfunction
Page 1 sur 1 La question posée dans ce topic a été résolue !
Vous ne pouvez pas poster de nouveaux sujets dans ce forum Vous ne pouvez pas répondre aux sujets dans ce forum Vous ne pouvez pas éditer vos messages dans ce forum Vous ne pouvez pas supprimer vos messages dans ce forum Vous ne pouvez pas voter dans les sondages de ce forum