- Joined
- Jun 30, 2008
- Messages
- 580
The Problem - When a hero gains 2 quests at the same time from a giver, when the hero kills units, the data collides
But: When you gain the quests seperatly they work fine.
But: When you gain the quests seperatly they work fine.
JASS:
library QuestLib initializer Init
globals
constant string QUEST_UPDATE = "|cff008000Quest Update:"
constant integer STRING_CAP = 5
constant string COMPLETE_COLOR = "|cff808080"
constant string UPDATE_STRING = " - "
constant string Lr = "|r"
constant integer TALK_ID = 'A000'
constant integer MAX_QUESTS = 200
constant real UPDATE_DURATION = 7.0
constant integer MAX_PLAYERS = 10
integer index = 0
hashtable q = InitHashtable()
endglobals
struct Players
unit hero
integer questindex
boolean array qenabled[MAX_QUESTS]
endstruct
struct QData
integer array kills[STRING_CAP]
integer array items[STRING_CAP]
boolean array complete[STRING_CAP]
endstruct
/* Quest Types:
Kill Quest - 1
Item Quest - 2
Travel Quest - 3
Event Quest - 4
*/
struct Quest
unit giver = null
integer qindex = 0
integer quests = 0
integer level = 0
integer killunits = 0
integer ritems = 0
integer exp = 0
integer gold = 0
integer lumber = 0
integer strings = 0
string intro = ""
string info = ""
string complete = ""
string reinfo = ""
string name = ""
integer array killunit[STRING_CAP]
integer array howmany[STRING_CAP]
string array unitname[STRING_CAP]
integer array rewarditem[12]
boolean array Qtypes[4]
method IntQuest takes unit u, integer i, string s returns nothing
set this.giver = u
set this.level = i
set this.name = s
set this.quests = this.quests+1
set index = index+1
set this.qindex = index
call SaveInteger(q, GetHandleId(this.giver), this.qindex, this)
endmethod
method IntKillQuest takes nothing returns nothing
set this.Qtypes[1] = true
set this.killunits = 0
endmethod
method IntKillUnit takes integer u, integer i, string n returns nothing
if this.Qtypes[1] != true then
call BJDebugMsg("Kill Quest Not Initialized")
else
if this.strings < STRING_CAP then
set this.killunits = this.killunits+1
set this.killunit[this.killunits] = u
set this.howmany[this.killunits] = i
set this.unitname[this.killunits] = n
set this.strings = this.strings+1
else
call BJDebugMsg("Max String Limit")
endif
call SaveInteger(q, u, this.qindex, this)
endif
endmethod
method AddRItem takes integer i returns nothing
set this.ritems = this.ritems+1
set this.rewarditem[this.ritems] = i
endmethod
method AddReward takes integer e, integer g, integer l returns nothing
set this.exp = e
set this.gold = g
set this.lumber = l
endmethod
method IntStrings takes string a, string b, string c, string d returns nothing
set this.intro = a
set this.info = b
set this.complete = c
set this.reinfo = d
endmethod
endstruct
private function talk takes nothing returns nothing
local real angle = GetUnitFacing(GetSpellTargetUnit())+180
local integer i = 0
local integer ii = 0
local Quest dat
local Players pdat = LoadInteger(q, GetHandleId(GetTriggerUnit()), GetPlayerId(GetOwningPlayer(GetTriggerUnit())))
local QData qdat = QData.create()
call BJDebugMsg(I2S(GetHandleId(pdat.hero)))
call BJDebugMsg(I2S(GetPlayerId(GetOwningPlayer(pdat.hero))))
loop
exitwhen ii > MAX_QUESTS
set ii = ii+1
set dat = LoadInteger(q, GetHandleId(GetSpellTargetUnit()), ii)
if dat.giver == GetSpellTargetUnit() then
if pdat.hero == GetTriggerUnit() then
set pdat.qenabled[dat.qindex] = true
loop
exitwhen i > dat.killunits
set i = i + 1
set qdat.kills[i] = 0
set qdat.complete[i] = false
endloop
call BJDebugMsg("Quest Accepted")
call BJDebugMsg(I2S(dat.qindex))
call SaveInteger(q, dat.qindex, GetHandleId(pdat.hero), qdat)
endif
endif
endloop
/*call SetCameraTargetControllerNoZForPlayer( GetOwningPlayer(GetTriggerUnit()), GetSpellTargetUnit(), 0, 0, false )
//call RotateCameraAroundLocBJ( 360.00, GetUnitLoc(GetTriggerUnit()), GetOwningPlayer(GetSpellTargetUnit()), 100000000.00 )
call SetCameraFieldForPlayer( GetOwningPlayer(GetTriggerUnit()), CAMERA_FIELD_ROTATION, angle, 3 )
call SetCameraFieldForPlayer( GetOwningPlayer(GetTriggerUnit()), CAMERA_FIELD_TARGET_DISTANCE, 250, 3 )
call SetCameraFieldForPlayer( GetOwningPlayer(GetTriggerUnit()), CAMERA_FIELD_ANGLE_OF_ATTACK, 0, 3 )
call SetCameraFieldForPlayer( GetOwningPlayer(GetTriggerUnit()), CAMERA_FIELD_ZOFFSET, 100, 3 )*/
endfunction
private function QuestUpdate takes player p, unit triggeru, unit killer returns nothing
local Players pdat = LoadInteger(q, GetHandleId(killer), GetPlayerId(p))
local Quest dat
local QData qdat
local integer i = 1
local integer c = 0
local integer ii = 1
call BJDebugMsg(I2S(GetHandleId(pdat.hero)))
call BJDebugMsg(I2S(GetPlayerId(GetOwningPlayer(pdat.hero))))
//Goes Through All Quests
loop
exitwhen ii > MAX_QUESTS
if pdat.hero == killer then
set dat = LoadInteger(q, GetUnitTypeId(triggeru), ii)
set qdat = LoadInteger(q, dat.qindex, GetHandleId(pdat.hero))
if dat.Qtypes[1] == true then
if pdat.qenabled[dat.qindex] == true then
loop
exitwhen i > dat.killunits
if dat.killunit[i] == GetUnitTypeId(triggeru) then
if (IsPlayerInForce(GetLocalPlayer(), GetForceOfPlayer(p))) then
// Use only local code (no net traffic) within this block to avoid desyncs.
call ClearTextMessages()
endif
call DisplayTimedTextToPlayer(p, 0, 0, UPDATE_DURATION, QUEST_UPDATE+Lr+" "+dat.name)
if dat.howmany[i] > qdat.kills[i] then
set qdat.kills[i] = qdat.kills[i] + 1
endif
endif
set i = i+1
endloop
set i = 1
//Goes Through All Units
loop
exitwhen i > dat.killunits
if dat.killunit[i] == GetUnitTypeId(triggeru) then
if dat.howmany[i] > qdat.kills[i] then
call DisplayTimedTextToPlayer(GetOwningPlayer(killer), 0, 0, UPDATE_DURATION, UPDATE_STRING+I2S(qdat.kills[i])+" / "+I2S(dat.howmany[i])+" "+dat.unitname[i] + " Killed!")
else
set qdat.complete[i] = true
set c = c+1
call DisplayTimedTextToPlayer(GetOwningPlayer(killer), 0, 0, UPDATE_DURATION, COMPLETE_COLOR+UPDATE_STRING+I2S(qdat.kills[i])+" / "+I2S(dat.howmany[i])+" "+dat.unitname[i] + " Killed!" + " (Complete)")
endif
else
if dat.howmany[i] > qdat.kills[i] then
call DisplayTimedTextToPlayer(GetOwningPlayer(killer), 0, 0, UPDATE_DURATION, UPDATE_STRING+I2S(qdat.kills[i])+" / "+I2S(dat.howmany[i])+" "+dat.unitname[i] + " Killed!")
else
set qdat.complete[i] = true
set c = c+1
call DisplayTimedTextToPlayer(GetOwningPlayer(killer), 0, 0, UPDATE_DURATION, COMPLETE_COLOR+UPDATE_STRING+I2S(qdat.kills[i])+" / "+I2S(dat.howmany[i])+" "+dat.unitname[i] + " Killed!" + " (Complete)")
endif
endif
if c == dat.strings then
call DisplayTimedTextToPlayer(GetOwningPlayer(killer), 0, 0, UPDATE_DURATION, UPDATE_STRING+"Return to " + GetUnitName(dat.giver))
endif
set i = i + 1
endloop
endif
endif
set ii = ii+1
endif
endloop
endfunction
function InitHero takes player p, unit u returns nothing
local Players pdat = Players.create()
local integer i = 1
set pdat.hero = u
loop
exitwhen i > MAX_QUESTS
set pdat.qenabled[i] = false
set i = i + 1
endloop
call SaveInteger(q, GetHandleId(pdat.hero), GetPlayerId(GetOwningPlayer(pdat.hero)), pdat)
call BJDebugMsg(I2S(GetHandleId(u)))
call BJDebugMsg(I2S(GetPlayerId(GetOwningPlayer(u))))
endfunction
private function KillDeath takes nothing returns nothing
call QuestUpdate(GetOwningPlayer(GetKillingUnit()), GetTriggerUnit(), GetKillingUnit())
endfunction
private function cond takes nothing returns boolean
if ( not ( GetSpellAbilityId() == TALK_ID ) ) then
return false
endif
return true
endfunction
private function KillCond takes nothing returns boolean
if ( not ( GetOwningPlayer(GetTriggerUnit()) == Player(PLAYER_NEUTRAL_AGGRESSIVE) ) ) then
return false
endif
return true
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerAddAction(t, function talk)
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function cond))
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_DEATH )
call TriggerAddCondition( t, Condition( function KillCond ) )
call TriggerAddAction( t, function KillDeath )
endfunction
endlibrary
JASS:
function InitQuests takes nothing returns nothing
local Quest KillBoar = Quest.create()
local Quest KillerP = Quest.create()
call KillBoar.IntQuest(gg_unit_Ntin_0022, 1, "Killer Boars")
call KillBoar.IntKillQuest()
call KillBoar.IntKillUnit('hfoo', 5, "Footmen")
call KillBoar.IntKillUnit('hrif', 2, "Riflemen")
call KillBoar.AddRItem('i000')
call KillBoar.AddReward(150, 15, 0)
call KillBoar.IntStrings(/*
*/"This is the intro!",/*
*/"This is the Info!",/*
*/"This is the Complete msg!",/*
*/"This is the reinfo!"/*
*/)
call KillerP.IntQuest(gg_unit_Ntin_0022, 1, "Bad Peasant")
call KillerP.IntKillQuest()
call KillerP.IntKillUnit('hpea', 4, "Peasant")
endfunction